Embed/microCLib

添加部分常用API。 添加 newlife rpc 通讯。
JiuHuan 编写于 2024-08-16 10:56:23
共计: 修改16个文件,增加1122行、删除59行。
修改 +121 -0
修改 +56 -0
修改 +1 -1
修改 +34 -0
修改 +6 -0
修改 +0 -33
修改 +0 -5
修改 +0 -1
修改 +15 -15
修改 +4 -4
增加 +161 -0
增加 +59 -0
增加 +393 -0
增加 +260 -0
修改 +10 -0
修改 +2 -0
修改 +121 -0
diff --git a/Core/Array.c b/Core/Array.c
index 1d8ba14..10ed1a1 100644
--- a/Core/Array.c
+++ b/Core/Array.c
@@ -243,3 +243,124 @@ bool ArrayEqual(byte* b1, byte* b2, int len)
 	return true;
 }
 
+static inline char tohex(byte by)
+{
+	if (by > 9)return by - 10 + 'A';
+	return by + '0';
+}
+
+int ArrayToHex(byte* bs, int len, char* hex)
+{
+	if (bs == NULL)return 0;
+	if (hex == NULL)return 0;
+
+	for (int i = 0; i < len; i++)
+	{
+		*hex++ = tohex(bs[i] >> 4);
+		*hex++ = tohex(bs[i] & 0x0f);
+	}
+
+	return len * 2;
+}
+
+static inline byte toby(char ch)
+{
+	if ((ch >= 'a') && (ch <= 'f'))return ch - 'A' + 10;
+	if ((ch >= 'A') && (ch <= 'F'))return ch - 'A' + 10;
+	if ((ch >= '0') && (ch <= '9'))return ch - '0';
+
+	return 0xff;
+}
+
+int HexToArray(char* hex, int len, byte* bs)
+{
+	if (hex == NULL)return 0;
+	if (bs == NULL)return 0;
+	len /= 2;
+
+	for (int i = 0; i < len; i++)
+	{
+		byte h = toby(hex[i * 2]);
+		byte l = toby(hex[i * 2 + 1]);
+
+		if (h == 0xff)return 0;
+		if (l == 0xff)return 0;
+
+		bs[i] = (h << 4) + l;
+	}
+
+	return len;
+}
+
+/// <summary>二分法查询</summary>
+/// <param name="array">从小到大排序的数组</param>
+/// <param name="len">数组长度</param>
+/// <param name="value">查询值</param>
+/// <returns>返回第一个有效值。 -1 未找到</returns>
+int DichotomyFind_Int(int* array, int len, int value)
+{
+	if (array == NULL)return -1;
+	if (len == 0)return -1;
+	if (len == 1)return array[0] == value ? 0 : -1;
+
+	int head = 0;
+	int tail = len - 1;
+
+	while (true)
+	{
+		int half = (head + tail) / 2;
+		int p = array[half];
+
+		if (value == p)
+		{
+			return half;
+		}
+		else if (value < p)
+		{
+			tail = half - 1;
+		}
+		else
+		{
+			head = half + 1;
+		}
+
+		if (head > tail)return -1;
+	}
+}
+
+/// <summary>二分法,从结构体查询</summary>
+/// <param name="array">结构体数组,按照KEY从小到大排序</param>
+/// <param name="len">结构体长度</param>
+/// <param name="func">获取KEY方法</param>
+/// <param name="key">查询项</param>
+/// <returns>返回第一个有效值。 -1 未找到</returns>
+int DichotomyFind_Obj(void* array, int len, DichotomyGetKey func, int key)
+{
+	if (array == NULL)return -1;
+	if (len == 0)return -1;
+	if (len == 1)return func(array,0) == key ? 0 : -1;
+
+	int head = 0;
+	int tail = len - 1;
+
+	while (true)
+	{
+		int half = (head + tail) / 2;
+		int p = func(array, half);
+
+		if (key == p)
+		{
+			return half;
+		}
+		else if (key < p)
+		{
+			tail = half - 1;
+		}
+		else
+		{
+			head = half + 1;
+		}
+
+		if (head > tail)return -1;
+	}
+}
修改 +56 -0
diff --git a/Core/Array.h b/Core/Array.h
index 938340e..514cc14 100644
--- a/Core/Array.h
+++ b/Core/Array.h
@@ -36,4 +36,60 @@ void ArraySortInt(int* data, int len);
 // 对比数组,相同返回true
 bool ArrayEqual(byte* b1, byte* b2, int len);
 
+// 数组转字符串,16进制
+int ArrayToHex(byte* bs, int len, char* hex);
+// len =>  hex.length 
+int HexToArray(char* hex, int len, byte* bs);
+
+
+/// <summary>二分法查询</summary>
+/// <param name="array">从小到大排序的数组</param>
+/// <param name="len">数组长度</param>
+/// <param name="value">查询值</param>
+/// <returns>返回第一个有效值。 -1 未找到</returns>
+int DichotomyFind_Int(int* array, int len, int value);
+
+
+
+/// <summary>提取KEY。二分法查询结构体时使用</summary>
+typedef int(*DichotomyGetKey)(void* array, int idx);
+
+/// <summary>二分法,从结构体查询</summary>
+/// <param name="array">结构体数组,按照KEY从小到大排序</param>
+/// <param name="len">结构体长度</param>
+/// <param name="func">获取KEY方法</param>
+/// <param name="key">查询项</param>
+/// <returns>返回第一个有效值。 -1 未找到</returns>
+int DichotomyFind_Obj(void* array, int len, DichotomyGetKey func, int key);
+
+/*
+* 二分法 从结构体查询  用法样例
+typedef struct
+{
+	int key;
+	int value;
+}Item_t;
+
+// DichotomyGetKey 类型的函数
+int ItemGetKey(void* array, int idx)
+{
+	Item_t* arr = (Item_t*)array;
+	return arr[idx].key;
+}
+
+int Test(void)
+{
+	Item_t Arr[50];
+
+	// 要查询的值
+	int findKey = 50;
+
+	int idx = DichotomyFind_Obj(Arr, ArrayLength(Arr), ItemGetKey, findKey);
+	return idx;
+}
+*
+*/
+
+
+
 
修改 +1 -1
diff --git a/Core/CircularQueue.c b/Core/CircularQueue.c
index 32195ad..3356d76 100644
--- a/Core/CircularQueue.c
+++ b/Core/CircularQueue.c
@@ -145,7 +145,7 @@ __INLINE bool CircularQueueRead(CircularQueue_t* queue, byte* pdata)
 	queue->pTail++;
 	if (queue->pTail >= queue->MemEnd)queue->pTail = queue->MemStart;
 
-	return false;
+	return true;
 }
 
 // 读数据, maxlen 是最大读取字节数,返回实际读出字节数
修改 +34 -0
diff --git a/Core/cJSON.c b/Core/cJSON.c
index a0ee381..4e51dec 100644
--- a/Core/cJSON.c
+++ b/Core/cJSON.c
@@ -1028,3 +1028,37 @@ void cJSON_Minify(char* json)
 	*into = 0;	// and null-terminate.
 }
 
+
+int JsonTryGetValue_Int(cJSON* json, char* name, int def)
+{
+	if (json == NULL)return def;
+	if (name == NULL)return def;
+
+	cJSON* obj = cJSON_GetObjectItem(json, name);
+	if (obj == NULL)return def;
+
+	return obj->valueint;
+}
+
+double JsonTryGetValue_Double(cJSON* json, char* name, double def)
+{
+	if (json == NULL)return def;
+	if (name == NULL)return def;
+
+	cJSON* obj = cJSON_GetObjectItem(json, name);
+	if (obj == NULL)return def;
+
+	return obj->valuedouble;
+}
+
+char* JsonTryGetValue_String(cJSON* json, char* name, char* def)
+{
+	if (json == NULL)return def;
+	if (name == NULL)return def;
+
+	cJSON* obj = cJSON_GetObjectItem(json, name);
+	if (obj == NULL)return def;
+
+	return obj->valuestring;
+}
+
修改 +6 -0
diff --git a/Core/cJSON.h b/Core/cJSON.h
index 3a42a58..026250c 100644
--- a/Core/cJSON.h
+++ b/Core/cJSON.h
@@ -139,3 +139,9 @@ void cJSON_Minify(char* json);
 // When assigning an integer value, it needs to be propagated to valuedouble too.
 #define cJSON_SetIntValue(object,val)			((object)?(object)->valueint=(object)->valuedouble=(val):(val))
 
+
+// 辅助功能
+int JsonTryGetValue_Int(cJSON* json, char* name, int def);
+double JsonTryGetValue_Double(cJSON* json, char* name, double def);
+char* JsonTryGetValue_String(cJSON* json, char* name, char* def);
+
修改 +0 -33
diff --git a/Core/cJsonProcess.c b/Core/cJsonProcess.c
index c6779cb..d0cac74 100644
--- a/Core/cJsonProcess.c
+++ b/Core/cJsonProcess.c
@@ -2,39 +2,6 @@
 #include "cJsonProcess.h"
 
 
-int JsonTryGetValue_Int(cJSON* json, char* name, int def)
-{
-	if (json == NULL)return def;
-	if (name == NULL)return def;
-
-	cJSON* obj = cJSON_GetObjectItem(json, name);
-	if (obj == NULL)return def;
-
-	return obj->valueint;
-}
-
-double JsonTryGetValue_Double(cJSON* json, char* name, double def)
-{
-	if (json == NULL)return def;
-	if (name == NULL)return def;
-
-	cJSON* obj = cJSON_GetObjectItem(json, name);
-	if (obj == NULL)return def;
-
-	return obj->valuedouble;
-}
-
-char* JsonTryGetValue_String(cJSON* json, char* name, char* def)
-{
-	if (json == NULL)return def;
-	if (name == NULL)return def;
-
-	cJSON* obj = cJSON_GetObjectItem(json, name);
-	if (obj == NULL)return def;
-
-	return obj->valuestring;
-}
-
 // 处理 Json
 bool JsonProcessMsg(Buffer2_t* buff, cJsonProcess_t* ProcessArray)
 {
修改 +0 -5
diff --git a/Core/cJsonProcess.h b/Core/cJsonProcess.h
index ae6f81f..96c6a05 100644
--- a/Core/cJsonProcess.h
+++ b/Core/cJsonProcess.h
@@ -29,11 +29,6 @@ typedef struct
 // ProcessArray 最后一项必须 ActionName = NULL 。 否则跑飞。
 bool JsonProcessMsg(Buffer2_t* buff, cJsonProcess_t* ProcessArray);
 
-// 辅助功能
-int JsonTryGetValue_Int(cJSON* json, char* name, int def);
-double JsonTryGetValue_Double(cJSON* json, char* name, double def);
-char* JsonTryGetValue_String(cJSON* json, char* name, char* def);
-
 /*
 使用方式
 
修改 +0 -1
diff --git a/Core/ConfigBase.h b/Core/ConfigBase.h
index 1718c04..b6fb9a1 100644
--- a/Core/ConfigBase.h
+++ b/Core/ConfigBase.h
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "Type.h"
-#include "CheckConfig.h"
 
 // 需要在自己项目内补充。 ConfigBase_t 只提供读写保存。
 #include "Config.h"
修改 +15 -15
diff --git a/Core/ModbusSlave.c b/Core/ModbusSlave.c
index 568e9ad..466fe21 100644
--- a/Core/ModbusSlave.c
+++ b/Core/ModbusSlave.c
@@ -10,7 +10,7 @@ void ModbusRtuMsgProcess(const ModbusSlave_t* mrs, byte* p, int pklen, void* sen
 	if (p == NULL)return;
 	if (pklen < 8)return;
 
-	ShowArray("485 ", p, pklen, pklen);
+	ShowArray("485 ", p, pklen, 16);
 	if (mrs == NULL)return;
 	if (mrs->SlaveAddr == NULL)return;
 
@@ -39,7 +39,7 @@ void ModbusRtuMsgProcess(const ModbusSlave_t* mrs, byte* p, int pklen, void* sen
 			if (mrs->BitAreas != NULL) AreaRead2(mrs->BitAreas, regaddr, txpy, bitcnt, true);
 			int txlen = MrcResult01a02(addr, cmd, txpy, bitcnt, tx, sizeof(tx));
 
-			ShowArray("-> ", tx, txlen, txlen);
+			ShowArray("-> ", tx, txlen, 16);
 			if (mrs->Send != NULL) mrs->Send(tx, txlen, sendparam);
 		}break;
 		// д�����Ȧ
@@ -51,7 +51,7 @@ void ModbusRtuMsgProcess(const ModbusSlave_t* mrs, byte* p, int pklen, void* sen
 
 			if (mrs->BitAreas != NULL) AreaWrite2(mrs->BitAreas, regaddr, &value, 1, true);
 
-			ShowArray("-> ", p, pklen, pklen);
+			ShowArray("-> ", p, pklen, 16);
 			if (mrs->Send != NULL) mrs->Send(p, pklen, sendparam);
 		}break;
 		// д�����ȦS
@@ -63,7 +63,7 @@ void ModbusRtuMsgProcess(const ModbusSlave_t* mrs, byte* p, int pklen, void* sen
 			if (mrs->BitAreas != NULL) AreaWrite2(mrs->BitAreas, regaddr, &p[7], bitcnt, true);
 			int txlen = MrcResult0f(addr, regaddr, bitcnt, tx, sizeof(tx));
 
-			ShowArray("-> ", tx, txlen, txlen);
+			ShowArray("-> ", tx, txlen, 16);
 			if (mrs->Send != NULL) mrs->Send(tx, txlen, sendparam);
 		}break;
 		case 3:	// ��������ּĴ���
@@ -80,7 +80,7 @@ void ModbusRtuMsgProcess(const ModbusSlave_t* mrs, byte* p, int pklen, void* sen
 			if (mrs->ByteAreas != NULL) AreaRead2(mrs->ByteAreas, regaddr * 2, txpy, regcnt * 2, false);
 			int txlen = MrcResult03a04(addr, cmd, txpy, regcnt, tx, sizeof(tx));
 
-			ShowArray("-> ", tx, txlen, txlen);
+			ShowArray("-> ", tx, txlen, 16);
 			if (mrs->Send != NULL) mrs->Send(tx, txlen, sendparam);
 		}
 		break;
@@ -92,7 +92,7 @@ void ModbusRtuMsgProcess(const ModbusSlave_t* mrs, byte* p, int pklen, void* sen
 			// modbus ��ַ��Ӧ���� 2�ֽڣ���ַ��Ҫ X2 ��Ӧ�ֽڿռ䡣
 			if (mrs->ByteAreas != NULL) AreaWrite2(mrs->ByteAreas, regaddr * 2, (byte*)&regdata, 2, false);
 
-			ShowArray("-> ", p, pklen, pklen);
+			ShowArray("-> ", p, pklen, 16);
 			if (mrs->Send != NULL) mrs->Send(p, pklen, sendparam);
 		}break;
 		case 0x10:
@@ -104,7 +104,7 @@ void ModbusRtuMsgProcess(const ModbusSlave_t* mrs, byte* p, int pklen, void* sen
 			if (mrs->ByteAreas != NULL) AreaWrite2(mrs->ByteAreas, regaddr * 2, &p[7], regcnt * 2, false);
 			int txlen = MrcResult10(addr, regaddr, regcnt, tx, sizeof(tx));
 
-			ShowArray("-> ", tx, txlen, txlen);
+			ShowArray("-> ", tx, txlen, 16);
 			if (mrs->Send != NULL) mrs->Send(tx, txlen, sendparam);
 		}break;
 
@@ -140,7 +140,7 @@ void ModbusTcpMsgProcess(const ModbusSlave_t* mrs, byte* pk, int pklen, void* se
 	if (pk == NULL)return;
 	if (pklen < 6 + 6)return;
 
-	ShowArray("Rev ", pk, pklen, pklen);
+	ShowArray("Rev ", pk, pklen, 16);
 	if (mrs == NULL)return;
 
 	byte* p = pk + 6;
@@ -169,7 +169,7 @@ void ModbusTcpMsgProcess(const ModbusSlave_t* mrs, byte* pk, int pklen, void* se
 		if (mrs->BitAreas != NULL)AreaRead2(mrs->BitAreas, regaddr, txpy, bitcnt, true);
 		int txlen = MtcResult01a02(head, cmd, txpy, bitcnt, tx, sizeof(tx));
 
-		ShowArray("-> ", tx, txlen, txlen);
+		ShowArray("-> ", tx, txlen, 16);
 		if (mrs->Send != NULL)mrs->Send(tx, txlen, sendparam);
 	}break;
 	// �������Ȧ
@@ -184,7 +184,7 @@ void ModbusTcpMsgProcess(const ModbusSlave_t* mrs, byte* pk, int pklen, void* se
 		if (mrs->BitAreas != NULL)AreaRead2(mrs->BitAreas, regaddr, txpy, bitcnt, true);
 		int txlen = MtcResult01a02(head, cmd, txpy, bitcnt, tx, sizeof(tx));
 
-		ShowArray("-> ", tx, txlen, txlen);
+		ShowArray("-> ", tx, txlen, 16);
 		if (mrs->Send != NULL)mrs->Send(tx, txlen, sendparam);
 	}break;
 	// д�����Ȧ
@@ -196,7 +196,7 @@ void ModbusTcpMsgProcess(const ModbusSlave_t* mrs, byte* pk, int pklen, void* se
 		byte value = regdata > 0 ? 0x01 : 0x00;
 		if (mrs->BitAreas != NULL)AreaWrite2(mrs->BitAreas, regaddr, &value, 1, true);
 
-		ShowArray("-> ", pk, pklen, pklen);
+		ShowArray("-> ", pk, pklen, 16);
 		if (mrs->Send != NULL)mrs->Send(pk, pklen, sendparam);
 	}break;
 	// д�����ȦS
@@ -208,7 +208,7 @@ void ModbusTcpMsgProcess(const ModbusSlave_t* mrs, byte* pk, int pklen, void* se
 		if (mrs->BitAreas != NULL)AreaWrite2(mrs->BitAreas, regaddr, &p[7], bitcnt, true);
 		int txlen = MtcResult0f(head, regaddr, bitcnt, tx, sizeof(tx));
 
-		ShowArray("-> ", tx, txlen, txlen);
+		ShowArray("-> ", tx, txlen, 16);
 		if (mrs->Send != NULL)mrs->Send(tx, txlen, sendparam);
 	}break;
 
@@ -227,7 +227,7 @@ void ModbusTcpMsgProcess(const ModbusSlave_t* mrs, byte* pk, int pklen, void* se
 		if (mrs->ByteAreas != NULL)AreaRead2(mrs->ByteAreas, regaddr * 2, txpy, regcnt * 2, false);
 		int txlen = MtcResult03a04(head, cmd, txpy, regcnt, tx, sizeof(tx));
 
-		ShowArray("-> ", tx, txlen, txlen);
+		ShowArray("-> ", tx, txlen, 16);
 		if (mrs->Send != NULL)mrs->Send(tx, txlen, sendparam);
 	}
 	break;
@@ -239,7 +239,7 @@ void ModbusTcpMsgProcess(const ModbusSlave_t* mrs, byte* pk, int pklen, void* se
 		// modbus ��ַ��Ӧ���� 2�ֽڣ���ַ��Ҫ X2 ��Ӧ�ֽڿռ䡣
 		if (mrs->ByteAreas != NULL)AreaWrite2(mrs->ByteAreas, regaddr * 2, (byte*)&regdata, 2, false);
 
-		ShowArray("-> ", pk, pklen, pklen);
+		ShowArray("-> ", pk, pklen, 16);
 		if (mrs->Send != NULL)mrs->Send(pk, pklen, sendparam);
 	}break;
 	case 0x10:
@@ -251,7 +251,7 @@ void ModbusTcpMsgProcess(const ModbusSlave_t* mrs, byte* pk, int pklen, void* se
 		if (mrs->ByteAreas != NULL)AreaWrite2(mrs->ByteAreas, regaddr * 2, &p[7], regcnt * 2, false);
 		int txlen = MtcResult10(head, regaddr, regcnt, tx, sizeof(tx));
 
-		ShowArray("-> ", tx, txlen, txlen);
+		ShowArray("-> ", tx, txlen, 16);
 		if (mrs->Send != NULL)mrs->Send(tx, txlen, sendparam);
 	}break;
 
修改 +4 -4
diff --git a/Core/ModbusTcpCodec.c b/Core/ModbusTcpCodec.c
index 21107bc..fde0edd 100644
--- a/Core/ModbusTcpCodec.c
+++ b/Core/ModbusTcpCodec.c
@@ -1,4 +1,4 @@
-
+
 #include "Type.h"
 #include "ModbusTcpCodec.h"
 #include "LengthFieldCodec.h"
@@ -15,7 +15,7 @@ int MtcGetLength(byte* p, int len)
 {
 	int res = LfcGetLength((LengthFieldCodec_t*)&Lfc, p, len);
 
-	if (res > 128)return -2;
+	if (res > 272)return -2;
 	if (res > 0)return res + 6;
 	return res;
 }
@@ -24,7 +24,7 @@ int MtcGetLenCircularQueue(CircularQueue_t* queue)
 {
 	int res = LfcGetLenCircularQueue((LengthFieldCodec_t*)&Lfc, queue);
 
-	if (res > 128)return -2;
+	if (res > 272)return -2;
 	if (res > 0)return res + 6;
 	return res;
 }
@@ -33,7 +33,7 @@ int MtcGetLenStream(Stream_t* st)
 {
 	int res = LfcGetLenStream((LengthFieldCodec_t*)&Lfc, st);
 
-	if (res > 128)return -2;
+	if (res > 272)return -2;
 	if (res > 0)return res + 6;
 	return res;
 }
增加 +161 -0
diff --git a/Core/MyList.c b/Core/MyList.c
new file mode 100644
index 0000000..9357acd
--- /dev/null
+++ b/Core/MyList.c
@@ -0,0 +1,161 @@
+
+#include "MyList.h"
+
+// #define ListPrintf		DebugPrintf
+#define ListPrintf(...)
+
+/*
+后期优化措施,减少malloc  free   使用C# List策略    批量申请,自动扩容。
+另外  如果重要数据,上层做处理,定期写入Flash然后 再读出,避免内存泄漏!!!
+*/
+
+void ListInit(MyList_t* list)
+{
+	list->head = NULL;
+	list->count = 0;
+}
+
+bool ListAdd(MyList_t* list, void* data, isEquiFunc isEqui)
+{
+	if ((list->head) == NULL)
+	{
+		MyListItem_t* item = (MyListItem_t*)MyListMalloc(sizeof(MyListItem_t));
+		if (!item)return false;
+		ListPrintf("ListAdd Item %08X : %08X\r\n", item, data);
+		item->Data = data;
+		item->_next = NULL;
+		list->count = 1;
+
+		list->head = item;
+		return true;
+	}
+	else
+	{
+		if (isEqui != NULL)
+		{
+			if (ListFindItem(list, data, isEqui) != NULL)
+			{
+				ListPrintf("ListAdd this data exist.\r\n");
+				return true;
+			}
+		}
+		MyListItem_t* item = (MyListItem_t*)MyListMalloc(sizeof(MyListItem_t));
+		if (!item)return false;
+		ListPrintf("ListAdd Item %08X : %08X\r\n", item, data);
+		item->Data = data;
+		item->_next = list->head;
+
+		list->count++;
+		list->head = item;
+		return true;
+	}
+}
+
+void* ListFind(MyList_t* list, void* data, isEquiFunc isEqui)
+{
+	MyListItem_t* item = list->head;
+	while (1)
+	{
+		if (item == NULL)break;
+
+		if (isEqui(item->Data, data))break;
+
+		item = item->_next;
+	}
+	if (item != NULL) return item->Data;
+	return NULL;
+}
+
+MyListItem_t* ListFindItem(MyList_t* list, void* data, isEquiFunc isEqui)
+{
+	MyListItem_t* item = list->head;
+	while (1)
+	{
+		if (item == NULL)break;
+
+		if (isEqui(item->Data, data))break;
+
+		item = item->_next;
+	}
+	return item;
+}
+
+bool ListRemove(MyList_t* list, void* data, isEquiFunc isEqui)
+{
+	MyListItem_t* pre = list->head;
+	MyListItem_t* item = list->head;
+	while (1)
+	{
+		if (item == NULL)break;
+
+		if (isEqui(item->Data, data))
+		{
+			if (pre == item)
+				list->head = item->_next;
+			else
+				pre->_next = item->_next;
+
+			list->count--;
+			ListPrintf("ListRemove Item %08X : %08X\r\n", item, item->Data);
+			MyListFree(item);
+			return true;
+		}
+		pre = item;
+		item = item->_next;
+	}
+	return false;
+}
+
+bool ListRemoveWithCallBack(MyList_t* list, void* data, isEquiFunc isEqui, ListCallBack callBack)
+{
+	MyListItem_t* pre = list->head;
+	MyListItem_t* item = list->head;
+	while (1)
+	{
+		if (item == NULL)break;
+
+		if (isEqui(item->Data, data))
+		{
+			if (pre == item)
+				list->head = item->_next;
+			else
+				pre->_next = item->_next;
+
+			list->count--;
+			ListPrintf("ListRemove Item %08X : %08X  &  callback:\r\n", item, item->Data);
+			callBack(item->Data);
+			MyListFree(item);		// while内有判断  此处item不为NULL
+			return true;
+		}
+		pre = item;
+		item = item->_next;
+	}
+
+	return false;
+}
+
+void* ListChange(MyList_t* list, void* src, void* dst, isEquiFunc isEqui)
+{
+	// if ((*head) == NULL)return NULL;
+
+	MyListItem_t* item = list->head;
+	while (1)
+	{
+		if (item == NULL)break;;
+
+		if (isEqui(item->Data, src))
+		{
+			ListPrintf("ListChange Item %08X   %08X -> %08X\r\n", item, src, dst);
+			item->Data = dst;
+			break;
+		}
+		item = item->_next;
+	}
+	if (item == NULL)
+	{
+		ListPrintf("ListChange Fail,src exist\r\n");
+		return NULL;
+	}
+
+	return item->Data;
+}
增加 +59 -0
diff --git a/Core/MyList.h b/Core/MyList.h
new file mode 100644
index 0000000..713ab3c
--- /dev/null
+++ b/Core/MyList.h
@@ -0,0 +1,59 @@
+#pragma once
+
+#ifndef __MyList_H__
+#define __MyList_H__
+
+#include "Type.h"
+#include "Debug.h"
+
+#include "FreeRTOS.h"
+
+
+#define MyListMalloc pvPortMalloc
+#define MyListFree vPortFree
+
+// 内部使用一些Cache,避免 malloc 太占 cpu 资源
+// #define ListItemCacheSize 5
+
+/*
+	List结构
+	单向链表,一个数据指针,一个结构体next指针。
+	对比数据是否相等,采用钩子函数完成。isEquiFunc  多半函数提供此钩子
+	删除数据项的时候提供其它动作的ListCallBack钩子,可以做数据项释放等操作。
+	强烈建议  定义了List_t 后 ListInit()初始化一下  避免拿到的内存有脏数据。
+*/
+
+struct MyListItem
+{
+	void*		Data;		// 链表数据项
+	struct MyListItem* _next;	// 链表连接项
+};
+typedef struct MyListItem MyListItem_t;
+
+typedef struct
+{
+	MyListItem_t* head;	// 头指针
+	int count;			// 数据项计数
+}MyList_t;
+
+typedef bool(*isEquiFunc)(void* data1, void* data2);
+typedef bool(*ListCallBack)(void* data);
+
+void ListInit(MyList_t* list);
+
+bool ListAdd(MyList_t* list, void* data, isEquiFunc isEqui);
+
+void* ListFind(MyList_t* list, void* data, isEquiFunc isEqui);
+
+bool ListRemove(MyList_t* list, void* data, isEquiFunc isEqui);
+
+bool ListRemoveWithCallBack(MyList_t* list, void* data, isEquiFunc isEqui, ListCallBack callBack);
+
+void* ListChange(MyList_t* list, void* src, void* dst, isEquiFunc isEqui);
+
+// 纠结是否放出来使用
+MyListItem_t* ListFindItem(MyList_t* list, void* data, isEquiFunc isEqui);
+
+
+#endif // !__List_H__
+
增加 +393 -0
diff --git a/Core/RpcMsg.c b/Core/RpcMsg.c
new file mode 100644
index 0000000..3f98d05
--- /dev/null
+++ b/Core/RpcMsg.c
@@ -0,0 +1,393 @@
+#include "RpcMsg.h"
+#include "Stream.h"
+// #include "Array.h"
+#include "Debug.h"
+
+// StreamCurrPoint() ����ȫ�������ٶ������١����ļ������жϺܶ࣬����ֱ��ȡָ��ͺá�
+#define StCurPoint(st)  (&st->MemStart[st->Position])
+
+
+/// <summary>NewLife SRMP ���ݰ���ȡ����</summary>
+/// <param name="data">������</param>
+/// <param name="len">����������</param>
+/// <returns>�������ݰ����ȣ�С��0����ȡʧ��</returns>
+int SrmpTryGetLen(byte* data, int len)
+{
+	int remain = len;
+	if (remain < sizeof(SrmpHead_t))return -1;
+
+	// ��׼��
+	SrmpHead_t* head = (SrmpHead_t*)data;
+	int pklen = 0;
+
+	if (head->Length != 0xffff)
+	{
+		pklen = head->Length + sizeof(SrmpHead_t);
+	}
+	else
+	{
+		// ��չ Head.LengthExt
+		if (remain < sizeof(SrmpHead_t) + 4)return -1;
+
+		uint lenExt = 0;
+		memcpy(&lenExt, ((byte*)head) + 4, 4);
+
+		pklen = lenExt + sizeof(SrmpHead_t) + 4;
+	}
+
+	if (remain < pklen)return -1;
+	return pklen;
+}
+
+/// <summary>NewLife SRMP ���ݰ���ȡ����</summary>
+/// <param name="st">��</param>
+/// <returns></returns>
+int SrmpTryGetLen_Stream(Stream_t* st)
+{
+	return SrmpTryGetLen(StCurPoint(st), StreamRemian(st));
+}
+
+/// <summary>NewLife SRMP ���ݰ���ȡ����</summary>
+/// <param name="queue">�����</param>
+/// <returns>�������ݰ����ȣ�С��0����ȡʧ��</returns>
+int SrmpTryGetLen_CircularQueue(CircularQueue_t* queue)
+{
+	byte cache[8];
+	SrmpHead_t* head = (SrmpHead_t*)cache;
+	int read = CircularQueueReads(queue, cache, sizeof(SrmpHead_t) + 4, true);
+	if (read < sizeof(SrmpHead_t))return -1;
+
+	int pklen = 0;
+	if (head->Length != 0xffff)
+	{
+		pklen = head->Length + sizeof(SrmpHead_t);
+	}
+	else
+	{
+		if (read < sizeof(SrmpHead_t) + 4)return -1;
+
+		uint lenExt = 0;
+		memcpy(&lenExt, ((byte*)head) + 4, 4);
+
+		pklen = lenExt + sizeof(SrmpHead_t) + 4;
+	}
+
+	if (CircularQueueGetLength(queue) < pklen)return -1;
+	return pklen;
+}
+
+
+
+
+
+// Head.Flag �� 6bit ָ��ֵ��
+#define HEAD_FLAG_0_5  0x00
+
+// �������ݰ������� 65535 �ֽڵ����ݰ������� Head.LengthExt
+#define BIG_PKT 0
+
+
+static int _RpcInit(byte* data, int datalen,
+	char* action, int act_len,
+	bool replay, int errCode,
+	RpcInfo_t* rpc)
+{
+	if (datalen < 9)return -1;
+	memset(data, 0x00, sizeof(SrmpHead_t));
+
+	rpc->Head = (SrmpHead_t*)data;
+	rpc->Reply = replay;
+	rpc->ErrCode = errCode;
+	rpc->Head->Flag = HEAD_FLAG_0_5;
+	if (replay) rpc->Head->Flag = 0x80 | HEAD_FLAG_0_5;
+	// rpc->Head->Seq = 0;
+
+	Stream_t pkst;
+	Stream_t* st = &pkst;
+	StreamInit(st, data, datalen);
+	StreamSeek(st, sizeof(SrmpHead_t), SeekBegin);
+
+	// action.length��7λѹ�����룩+ action
+	StreamWriteCompressionUint(st, act_len);
+
+	rpc->Action = (char*)StCurPoint(st);
+	rpc->ActionLen = act_len;
+	if (StreamWriteBytes(st, (byte*)action, act_len) != act_len)
+	{
+		DebugPrintf("ApiPacket %s datalen less\r\n", action);
+		return -2;
+	}
+
+	// �����봦��
+	if ((errCode != 0) && replay)
+	{
+		rpc->Head->Flag |= 0x40;
+		StreamWriteUint(st, (uint)errCode);
+	}
+
+	// ���һ�����ȣ�����������⡣
+	if (StreamRemian(st) < 4)
+	{
+		rpc->Payload = NULL;
+		rpc->PayloadLen = 0;
+
+		return -3;
+	}
+
+	// payload.length(int) + payload
+	StreamSeek(st, 4, SeekCurrent);
+
+	rpc->Payload = StCurPoint(st);
+	rpc->PayloadLen = 0;
+
+	return StreamRemian(st);
+}
+
+/// <summary>��װ RPC ͨѶ��ʽ</summary>
+/// <param name="data">�ڴ滺��</param>
+/// <param name="datalen">�ڴ��С</param>
+/// <param name="action">RPC ����</param>
+/// <param name="rpc">RPC ����</param>
+/// <returns>���ظ�����������󳤶�</returns>
+int RpcInit(byte* data, int datalen, char* action, RpcInfo_t* rpc)
+{
+	if (data == NULL)return -1;
+	if (action == NULL)return -1;
+
+	int slen = strlen(action);
+#if BIG_PKT
+	return _RpcInit(data + 4, datalen - 4, action, slen, false, 0, rpc);
+#else
+	return _RpcInit(data, datalen, action, slen, false, 0, rpc);
+#endif
+}
+
+/// <summary>��װ RPC ������Ϣ����</summary>
+/// <param name="data">�ڴ滺��</param>
+/// <param name="datalen">�ڴ��С</param>
+/// <param name="action">RPC ����</param>
+/// <param name="errCode">�����룬0�޴�</param>
+/// <param name="rpc">RPC ����</param>
+/// <returns>���ظ�����������󳤶�</returns>
+int RpcReplyInit(byte* data, int datalen, char* action, uint errCode, RpcInfo_t* rpc)
+{
+	if (data == NULL)return -1;
+	if (action == NULL)return -1;
+
+	int slen = strlen(action);
+#if BIG_PKT
+	return _RpcInit(data + 4, datalen - 4, action, slen, true, errCode, rpc);
+#else
+	return _RpcInit(data, datalen, action, slen, true, errCode, rpc);
+#endif
+}
+
+/// <summary>�����ظ���Ϣ</summary>
+/// <param name="data">������</param>
+/// <param name="datalen">��������С</param>
+/// <param name="errCode">�����룬0�޴�</param>
+/// <param name="src">ԭ����Ϣ</param>
+/// <param name="dst">����������Ϣ</param>
+/// <returns>�������ߴ�</returns>
+int RpcCreatReply(byte* data, int datalen, uint errCode, RpcInfo_t* src, RpcInfo_t* dst)
+{
+	if (data == NULL)return -1;
+	if (src == NULL)return -1;
+	if (src->Head == NULL)return -1;
+	if (src->Action == NULL)return -1;
+#if BIG_PKT
+	if (datalen < 9 + 4)return -1;
+	// ��actionlen=0����С���ݰ� 9 + 4 �ֽڡ�
+	if (src->ActionLen + 9 + 4 > datalen)return -1;
+#else
+	if (datalen < 9)return -1;
+	// ��actionlen=0����С���ݰ� 9�ֽڡ�
+	if (src->ActionLen + 9 > datalen)return -1;
+#endif
+
+	byte Flag = src->Head->Flag & 0x3f;
+	byte Seq = src->Head->Seq;
+
+	int pyMax = _RpcInit(data, datalen, src->Action, src->ActionLen, true, errCode, dst);
+	dst->Head->Flag &= 0xc0;
+	dst->Head->Flag |= Flag;
+	dst->Head->Seq = Seq;
+
+	return pyMax;
+}
+
+/// <summary>����/���� RPC ���ݰ��ṹ</summary>
+/// <param name="rpc">RPC ����</param>
+/// <returns>����������Ϣ����</returns>
+int RpcFix(RpcInfo_t* rpc)
+{
+	if (rpc == NULL)return -1;
+	if (rpc->Head == NULL)return -1;
+	if (rpc->Payload == NULL)return -1;
+
+	// ��䡾���س��ȡ�,�ڸ���ǰ��4�ֽ�
+	Stream_t pkst;
+	Stream_t* st = &pkst;
+	StreamInit(st, rpc->Payload - 4, 4);
+	StreamWriteUint(st, rpc->PayloadLen);
+
+	// ���ڴ�β-�ڴ�ͷ�� - ���ݰ�ͷ������
+	SrmpHead_t* head = rpc->Head;
+	uint hLen = (uint)rpc->Payload + rpc->PayloadLen - (uint)head - sizeof(SrmpHead_t);
+
+	// �������ݰ�
+	if (hLen < 65535)
+	{
+		head->Length = hLen;
+		return hLen + sizeof(SrmpHead_t);
+	}
+
+#if BIG_PKT
+	// �������ݰ��� ǰ������4�ֽڣ������ó���
+	// �ж� ��һ�ε��ñ�����
+	if ((uint)rpc->Action - (uint)rpc->Head - sizeof(SrmpHead_t) < 4)
+	{
+		byte* p = (byte*)rpc->Head;
+		SrmpHead_t* head = (SrmpHead_t*)(p - 4);
+		// �Ӻ�����ǰ copy �����ĸ������⣬ֱ���ϡ�
+		memcpy(head, rpc->Head, sizeof(SrmpHead_t));
+		// ���λ�λ��
+		rpc->Head = head;
+	}
+
+	// ���ȴ���
+	head->Length = 0xffff;
+	StreamInit(st, (byte*)rpc->Head, 8);
+	StreamSeek(st, sizeof(SrmpHead_t), SeekCurrent);
+	StreamWriteUint(st, hLen);
+
+	return hLen + sizeof(SrmpHead_t) + 4;
+#else
+	// ��֧�ֳ������ݰ�
+	return 0;
+#endif
+}
+
+/// <summary>����/���� RPC ���ݰ��ṹ</summary>
+/// <param name="rpc">RPC ����</param>
+/// <param name="seq">��ϢSEQ���</param>
+/// <returns>����������Ϣ����</returns>
+int RpcFixWithSeq(RpcInfo_t* rpc, byte seq)
+{
+	if (rpc == NULL)return 0;
+	if (rpc->Head == NULL)return 0;
+	rpc->Head->Seq = seq;
+
+	return RpcFix(rpc);
+}
+
+/// <summary>��������Seqֵ</summary>
+/// <param name="data">���ݰ�</param>
+/// <param name="seq">Seq</param>
+void RpcPktSetSeq(byte* data, byte seq)
+{
+	if (data == NULL)return;
+
+	SrmpHead_t* head = (SrmpHead_t*)data;
+	head->Seq = seq;
+}
+
+/// <summary>���RPC����</summary>
+/// <param name="data">����</param>
+/// <param name="len">���ݴ�С</param>
+/// <param name="rpc">rpc����</param>
+/// <returns>С��0��ʾ����</returns>
+int RpcPktParse(byte* data, int len, RpcInfo_t* rpc)
+{
+	if (data == NULL)return -1;
+	if (len < 9)return -1;
+	if (rpc == NULL)return -1;
+	memset(rpc, 0x00, sizeof(RpcInfo_t));
+
+	// HEAD
+	SrmpHead_t* head = (SrmpHead_t*)data;
+	if (head->Length < 65535)
+	{
+		if (head->Length + sizeof(SrmpHead_t) > len)return -2;
+	}
+
+	// FLAG ��־λ
+	if ((head->Flag & 0x80) != 0)rpc->Reply = true;
+	bool err = (head->Flag & 0x40) != 0;
+
+	Stream_t pkst;
+	Stream_t* st = &pkst;
+	StreamInit(st, data, len);
+	StreamSeek(st, sizeof(SrmpHead_t), SeekBegin);
+	// ���� 64K ���������� Head.LengthExt ��
+	if (head->Length == 0xffff)
+	{
+		uint realLen;
+		if (StreamReadUint(st, &realLen) != 4)return -2;
+		if (realLen + sizeof(SrmpHead_t) > len)return -2;
+	}
+
+	rpc->Head = head;
+
+	// action.length��7λѹ�����룩+ action
+	uint slen = 0;
+	StreamReadCompressionUint(st, &slen);
+	rpc->Action = (char*)StCurPoint(st);
+	rpc->ActionLen = slen;
+	StreamSeek(st, slen, SeekCurrent);
+	if (StreamRemian(st) == 0)return 0;
+
+	// errCode
+	if (err)
+	{
+		StreamReadUint(st, (uint*)&rpc->ErrCode);
+		if (StreamRemian(st) == 0)return 0;
+	}
+
+	// payload.length(int) + payload
+	StreamReadUint(st, (uint*)&rpc->PayloadLen);
+	rpc->Payload = StCurPoint(st);
+	// if (StreamRemian(st) < rpc->PayloadLen)return -5;
+
+	return 0;
+}
+
+/// <summary>��ӡRPC����</summary>
+void RpcShow(RpcInfo_t* rpc)
+{
+	if (rpc == NULL)return;
+	
+	DebugPrintf("F %02X S %02X [%d]",
+		rpc->Head->Flag,rpc->Head->Seq,rpc->Head->Length);
+
+	// �����ַ���β���޸�Ϊ \0 , ��ԭ�� 
+	byte act_e = rpc->Action[rpc->ActionLen];
+	
+	DebugPrintf(" ACT ");
+	if (rpc->Action != NULL)
+	{
+		rpc->Action[rpc->ActionLen] = '\0';
+		DebugPrintf("%s\r\n", rpc->Action);
+		rpc->Action[rpc->ActionLen] = act_e;
+	}
+	else
+	{
+		DebugPrintf(" --\r\n");
+	}
+
+	if (rpc->Payload != NULL)
+	{
+		byte pay_e = rpc->Payload[rpc->PayloadLen];
+		rpc->Payload[rpc->PayloadLen] = 0x00;
+		if (rpc->ErrCode != 0)
+			DebugPrintf(" ERR %d : %s\r\n", rpc->ErrCode, rpc->Payload);
+		else
+			DebugPrintf(" %s\r\n", rpc->Payload);
+		rpc->Payload[rpc->PayloadLen] = pay_e;
+	}
+	else
+	{
+		DebugPrintf(" --\r\n");
+	}
+}
+
增加 +260 -0
diff --git a/Core/RpcMsg.h b/Core/RpcMsg.h
new file mode 100644
index 0000000..485c78e
--- /dev/null
+++ b/Core/RpcMsg.h
@@ -0,0 +1,260 @@
+#pragma once
+
+#include "Type.h"
+
+/*
+* ��λ�����ᳬ�� 65535 �ĸ��أ����Բ�֧�ֳ������ݰ���
+*/
+
+#pragma pack(push)
+#pragma pack(1)
+
+// NewLife SRMP ��׼���ݰ�ͷ
+typedef struct
+{
+	// Flag Ϊλ��־
+	// bit7  0x80  Reply
+	// bit6  0x40  Error
+	// bit 0-5	   ���ݰ���ʽ��Ĭ��ʹ��0 
+	// �������
+	byte Flag;
+	// ���ݰ� Seq
+	byte Seq;
+	// ���ݳ��ȣ�С��
+	ushort Length;
+
+	// �������ݰ������� Length=0XFFFF��Ȼ�� LengthExt=ʵ�ʳ��ȡ�
+	// uint LengthExt;
+} SrmpHead_t;
+
+#pragma pack(pop)
+
+// Ҳ����д�� NewLifeHead_t
+#define NewLifeHead_t SrmpHead_t
+
+#include "Stream.h"
+#include "CircularQueue.h"
+
+/// <summary>NewLife SRMP ���ݰ���ȡ����</summary>
+/// <param name="data">������</param>
+/// <param name="len">����������</param>
+/// <returns>�������ݰ����ȣ�С��0����ȡʧ��</returns>
+int SrmpTryGetLen(byte* data, int len);
+
+/// <summary>NewLife SRMP ���ݰ���ȡ����</summary>
+/// <param name="st">��</param>
+/// <returns></returns>
+int SrmpTryGetLen_Stream(Stream_t* st);
+
+/// <summary>NewLife SRMP ���ݰ���ȡ����</summary>
+/// <param name="queue">�����</param>
+/// <returns>�������ݰ����ȣ�С��0����ȡʧ��</returns>
+int SrmpTryGetLen_CircularQueue(CircularQueue_t* queue);
+
+
+typedef struct
+{
+	// ͷ��
+	SrmpHead_t* Head;
+
+	// ������Ϣ
+	bool Reply;
+	// �������
+	int ErrCode;
+
+	// ��������
+	char* Action;
+	// �����ַ�������
+	uint ActionLen;
+
+	// ����
+	byte* Payload;
+	// ���س��ȡ� 
+	uint PayloadLen;
+}RpcInfo_t;
+
+/// <summary>��װ RPC ͨѶ��ʽ</summary>
+/// <param name="data">�ڴ滺��</param>
+/// <param name="datalen">�ڴ��С</param>
+/// <param name="action">RPC ����</param>
+/// <param name="rpc">RPC ����</param>
+/// <returns>���ظ�����������󳤶�</returns>
+int RpcInit(byte* data, int datalen, char* action, RpcInfo_t* rpc);
+
+/// <summary>��װ RPC ������Ϣ����</summary>
+/// <param name="data">�ڴ滺��</param>
+/// <param name="datalen">�ڴ��С</param>
+/// <param name="action">RPC ����</param>
+/// <param name="errCode">�����룬0�޴�</param>
+/// <param name="rpc">RPC ����</param>
+/// <returns>���ظ�����������󳤶�</returns>
+int RpcReplyInit(byte* data, int datalen, char* action, uint errCode, RpcInfo_t* rpc);
+
+/// <summary>�����ظ���Ϣ</summary>
+/// <param name="data">������</param>
+/// <param name="datalen">��������С</param>
+/// <param name="errCode">�����룬0�޴�</param>
+/// <param name="src">ԭ����Ϣ</param>
+/// <param name="dst">����������Ϣ</param>
+/// <returns>�������ߴ�</returns>
+int RpcCreatReply(byte* data, int datalen, uint errCode, RpcInfo_t* src, RpcInfo_t* dst);
+
+/// <summary>����/���� RPC ���ݰ��ṹ</summary>
+/// <param name="rpc">RPC ����</param>
+/// <returns>����������Ϣ����</returns>
+int RpcFix(RpcInfo_t* rpc);
+
+/// <summary>����/���� RPC ���ݰ��ṹ</summary>
+/// <param name="rpc">RPC ����</param>
+/// <param name="seq">��ϢSEQ���</param>
+/// <returns>����������Ϣ����</returns>
+int RpcFixWithSeq(RpcInfo_t* rpc, byte seq);
+
+/// <summary>��������Seqֵ</summary>
+/// <param name="data">���ݰ�</param>
+/// <param name="seq">Seq</param>
+void RpcPktSetSeq(byte* data, byte seq);
+
+/// <summary>���RPC����</summary>
+/// <param name="data">����</param>
+/// <param name="len">���ݴ�С</param>
+/// <param name="rpc">rpc����</param>
+/// <returns>С��0��ʾ����</returns>
+int RpcPktParse(byte* data, int len, RpcInfo_t* rpc);
+
+/// <summary>��ӡRPC����</summary>
+void RpcShow(RpcInfo_t* rpc);
+
+/*
+
+/// <summary>ƥ������/��ά��</summary>
+/// <param name="codestr">����/����</param>
+/// <param name="buff"></param>
+/// <param name="bufflen"></param>
+/// <returns></returns>
+int BuildMatchMsg(char* codestr, int posi, byte* buff, int bufflen)
+{
+	char* qr = codestr;
+	if (qr == NULL)qr = "null";
+	int result = -1;
+
+	RpcInfo_t rpc;
+	int maxlen = RpcInit(buff, bufflen, "HdDev/Match", &rpc);
+
+	cJSON* root = cJSON_CreateObject();
+	cJSON_AddItemToObject(root, "Qr", cJSON_CreateString(qr));
+	// cJSON_AddItemToObject(root, "Uid", cJSON_CreateString(SysInfo.Uid));
+	cJSON_AddItemToObject(root, "Offset", cJSON_CreateNumber(posi));
+
+	char* msgbuff = cJSON_PrintUnformatted(root);
+	if (msgbuff == NULL) { cJSON_Delete(root); return -1; }
+
+	int pylen = strlen(msgbuff);
+	if (pylen == 0)
+	{
+		result = -2;
+	}
+	else if (pylen < maxlen)
+	{
+		rpc.PayloadLen = pylen;
+		memcpy(rpc.Payload, msgbuff, pylen);
+
+		int pklen = RpcFix(&rpc);
+		result = pklen;
+	}
+
+	// ʹ�� cJSON_Delete ��ʹ�õ� free ����
+	if (cJSON_free)cJSON_free(msgbuff);
+	else GlobleFree(msgbuff);
+
+	cJSON_Delete(root);
+	return result;
+}
+
+/// <summary>ƥ������/��ά��</summary>
+/// <param name="codestr">����/����</param>
+/// <param name="buff"></param>
+/// <param name="bufflen"></param>
+/// <returns></returns>
+int BuildMatchMsg(char* codestr, int posi, byte* buff, int bufflen)
+{
+	RpcInfo_t rpc;
+	int maxlen = RpcInit(buff, bufflen, "HdDev/Match", &rpc);
+	rpc.PayloadLen = snprintf(rpc.Payload, maxlen,
+		"{\"Qr\":\"%s\",\"Uid\":\"%s\",\"Offset\":%d} ", codestr, SysInfo.Uid, posi);
+
+	int pklen = RpcFix(&rpc);
+	return pklen;
+}
+
+
+/// <summary>�������ݰ�����</summary>
+/// <param name="data"></param>
+/// <param name="bufflen"></param>
+void NetDataProcess(byte* data, int bufflen)
+{
+	// ��С���ݳ��ȣ�����Ҫ������ͷ�����ɡ�
+	if (bufflen < sizeof(SrmpHead_t))return;
+
+	SrmpHead_t* head = (SrmpHead_t*)data;
+	if (head->Length == 0)	return;
+	if (head->Length + sizeof(SrmpHead_t) > bufflen)	return;
+
+	RpcInfo_t rpc;
+	int err = RpcPktParse(data, bufflen, &rpc);
+	if (err < 0)
+	{
+		DebugPrintf("RpcPktParse %d\r\n", err);
+		return;
+	}
+
+	// ���ַ������־\0 �����ƻ���Ϣ���ݣ�ȷ���������Ӱ���ʹ�á�
+	rpc.Action[rpc.ActionLen] = '\0';
+	rpc.Payload[rpc.PayloadLen] = '\0';
+
+	if (!rpc.Reply)
+	{
+		// ������Ϣ������
+		// DebugPrintf("RpcPktParse %d\r\n", err);
+
+		// ��֧�ֱ�����Ĵ���
+		static byte cache[80];
+		RpcInfo_t rs;
+		int maxlen = RpcCreatReply(cache, sizeof(cache), 400, &rpc, &rs);
+		memcpy(rs.Payload,"Not support",11);
+		rs.PayloadLen = 11;
+		int pklen = RpcFix(&rs);
+
+		DebugPrintf("SEND ");
+		RpcShow(&rs);
+
+		DSend((byte*)rs.Head, pklen);
+
+		return;
+	}
+	else
+	{
+		// �ظ���Ϣ����
+		//		�����ӡ����
+		if (rpc.ErrCode != 0)
+		{
+			DebugPrintf("Rev %s Err %d\r\n\t%s\r\n", rpc.Action, rpc.ErrCode, rpc.Payload);
+			return;
+		}
+
+		//		��action�б����ҵ���Ӧ�Ĵ����������д���
+		DebugPrintf("Rev %s %d\r\n\t%s\r\n", rpc.Action, rpc.ErrCode, rpc.Payload);
+		for (int i = 0; i < sizeof(ActionProcess) / sizeof(ActionProcess[0]); i++)
+		{
+			if (strcmp(rpc.Action, ActionProcess[i].action) == 0)
+			{
+				ActionFunction_t pro = ActionProcess[i].Process;
+				if (pro != NULL) pro(rpc.Payload, rpc.PayloadLen, &rpc);
+				return;
+			}
+		}
+	}
+}
+
+*/
+
修改 +10 -0
diff --git a/Core/Stream.c b/Core/Stream.c
index 008f558..5d326f4 100644
--- a/Core/Stream.c
+++ b/Core/Stream.c
@@ -11,6 +11,16 @@ void StreamInit(Stream_t* st, byte* p, int len)
 	st->Size = len;
 }
 
+byte* StreamCurrPoint(Stream_t* st)
+{
+	if (st == NULL)return NULL;
+	if (st->MemStart == NULL)return NULL;
+	// if (st->Size < 1)return NULL;
+	if (st->Position >= st->Size)return NULL;
+
+	return &st->MemStart[st->Position];
+}
+
 int StreamWriteByte(Stream_t* st, byte data)
 {
 	if (st == NULL)return 0;
修改 +2 -0
diff --git a/Core/Stream.h b/Core/Stream.h
index e08a766..f6dee80 100644
--- a/Core/Stream.h
+++ b/Core/Stream.h
@@ -25,6 +25,8 @@ typedef enum
 }SeekOrigin_e;
 
 void StreamInit(Stream_t* st, byte* p, int len);
+// 当前游标对应的指针位置。
+byte* StreamCurrPoint(Stream_t* st);
 
 int StreamWriteByte(Stream_t* st, byte data);
 int StreamWriteUshort(Stream_t* st, ushort data);