[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/zte_ping/Makefile b/ap/app/zte_ping/Makefile
new file mode 100755
index 0000000..3a64296
--- /dev/null
+++ b/ap/app/zte_ping/Makefile
@@ -0,0 +1,94 @@
+# /*****************************************************************************
+#* °æÈ¨ËùÓÐ (C)2015, ÖÐÐËͨѶ¹É·ÝÓÐÏÞ¹«Ë¾¡£
+#* 
+#* ÎļþÃû³Æ:     Makefile
+#* Îļþ±êʶ:     Makefile
+#* ÄÚÈÝÕªÒª:     Makefile of ZTE applications
+#* ʹÓ÷½·¨:     void
+#* 
+#* ÐÞ¸ÄÈÕÆÚ        °æ±¾ºÅ      Ð޸ıê¼Ç        ÐÞ¸ÄÈË          ÐÞ¸ÄÄÚÈÝ
+#* -----------------------------------------------------------------------------
+#* 2015/03/12      V1.0        Create          ²ÜÈü          ´´½¨
+#* 
+# ******************************************************************************/
+
+#*******************************************************************************
+# include ZTE application makefile
+#*******************************************************************************
+.EXPORT_ALL_VARIABLES:
+ifeq ($(LINUX_TYPE),uClinux)
+include $(COMMON_MK)
+endif
+#include ../net_team.mk
+#*******************************************************************************
+# execute
+#*******************************************************************************
+EXEC = zping
+
+#*******************************************************************************
+# objects
+#*******************************************************************************
+OBJSRC    = $(filter-out zping.c,$(wildcard *.c))
+OBJS = $(patsubst %.c,%.o,$(OBJSRC))
+
+#*******************************************************************************
+# include path
+#*******************************************************************************
+ifeq ($(LINUX_TYPE),uClinux)
+CFLAGS += -I../include  -I$(zte_lib_path)/libnl_2/libnl-2.0/include -lnl -lm  -L$(zte_lib_path)/libnl_2/libnl-2.0/lib/.libs
+CFLAGS += -Wl,--allow-multiple-definition,-elf2flt=-s131072
+else
+#CFLAGS += -I../include  -I$(ROOT_PATH)/lib/zte_libs/libnl_2/libnl-2.0/include -lnl -lm  -L$(ROOT_PATH)/lib/zte_libs/libnl_2/libnl-2.0/lib/.libs
+CFLAGS += -I../include  -I$(zte_lib_path)/libnl_2/libnl-2.0/include -lnl -lm  -L$(zte_lib_path)/libnl_2/libnl-2.0/lib/.libs
+endif
+
+CFLAGS += -g
+CFLAGS += -I../include                                                   
+CFLAGS += -g -Werror=implicit-function-declaration
+#*******************************************************************************
+# macro definition
+#*******************************************************************************
+ifeq ($(CUSTOM_MODEL), MF29S2)
+CFLAGS	+= -DCUSTOM_VERSION_MF29S2_ZTE
+endif
+#CPPFLAGS += -D_MBB_OS_UCLINUX
+#*******************************************************************************
+# library
+#*******************************************************************************
+
+LDLIBS += -lsoft_timer_sc
+LDLIBS += -lsoftap
+LDLIBS += -lpthread -lnl -lm -lnvram_sc
+LDLIBS += -L$(zte_lib_path)/libnvram
+LDLIBS += -L$(zte_lib_path)/libsoft_timer
+LDLIBS  += -L$(zte_lib_path)/libsoftap
+CFLAGS += -I$(zte_lib_path)/libnvram
+ifeq ($(LINUX_TYPE),uClinux)
+LDFLAGS += -L$(zte_lib_path)/libnl_2/libnl-2.0/lib/.libs -Wl,--allow-multiple-definition
+else
+#LDFLAGS += -L$(ROOT_PATH)/lib/zte_libs/libnl_2/libnl-2.0/lib/.libs
+LDFLAGS += -L$(zte_lib_path)/libnl_2/libnl-2.0/lib/.libs 
+endif
+
+#*******************************************************************************
+# library path
+#*******************************************************************************
+
+#*******************************************************************************
+# targets
+#*******************************************************************************
+all: $(EXEC)
+
+$(EXEC): $(OBJS)
+	$(CC) $(CFLAGS)  -o $@ $(EXEC).c $(OBJS) -Wl,--start-group $(LDLIBS) -Wl,--end-group $(LDFLAGS)
+
+$(OBJS):%.o:%.c
+	$(CC) $(CFLAGS) -c $<
+
+romfs root_fs:
+	#$(ROMFSINST) /bin/$(EXEC)
+	cp -v zping ../test_tools/
+
+clean:
+	-rm -f $(EXEC) *.elf *.gdb *.o
+
diff --git a/ap/app/zte_ping/error.c b/ap/app/zte_ping/error.c
new file mode 100755
index 0000000..b39a376
--- /dev/null
+++ b/ap/app/zte_ping/error.c
@@ -0,0 +1,49 @@
+
+#include "headers.h"
+#include "util.h"
+
+/* -------------------------------------------------------------------
+ * warn
+ *
+ * Prints message and return
+ * ------------------------------------------------------------------- */
+
+void warn(const char *inMessage, const char *inFile, int inLine)
+{
+	fflush(0);
+
+//#ifdef NDEBUG
+//    fprintf( stderr, "%s failed\n", inMessage );
+//#else
+
+	/* while debugging output file/line number also */
+	fprintf(stderr, "%s failed (%s:%d)\n", inMessage, inFile, inLine);
+//#endif
+} /* end warn */
+
+/* -------------------------------------------------------------------
+ * warn_errno
+ *
+ * Prints message and errno message, and return.
+ * ------------------------------------------------------------------- */
+
+void warn_errno(const char *inMessage, const char *inFile, int inLine)
+{
+	int my_err;
+	const char* my_str;
+
+	/* get platform's errno and error message */
+	my_err = errno;
+	my_str = strerror(my_err);
+
+	fflush(0);
+
+//#ifdef NDEBUG
+//    fprintf( stderr, "%s failed: %s\n", inMessage, my_str );
+//#else
+
+	/* while debugging output file/line number and errno value also */
+	fprintf(stderr, "%s failed (%s:%d): %s (%d)\n",
+	        inMessage, inFile, inLine, my_str, my_err);
+//#endif
+} /* end warn_errno */
diff --git a/ap/app/zte_ping/headers.h b/ap/app/zte_ping/headers.h
new file mode 100755
index 0000000..83661ce
--- /dev/null
+++ b/ap/app/zte_ping/headers.h
@@ -0,0 +1,60 @@
+
+#ifndef HEADERS_H
+#define HEADERS_H
+
+//#include "config.h"
+
+//#define WIN32_LEAN_AND_MEAN /* exclude unnecesary headers */
+/*
+#include <windows.h>
+#include <winsock2.h>
+//#include <ws2tcpip.h>
+#include <windows.h>
+#pragma comment(lib,"ws2_32.lib")
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <process.h>
+#include <tchar.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+#include <time.h>
+#include <math.h>
+
+#include <pthread.h>
+#pragma comment(lib, "pthreadVC2.lib")
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <unistd.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <pthread.h>
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <netinet/tcp.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sched.h>
+#include <setjmp.h>
+#include <signal.h>
+
+#define SOCKET_ERROR   -1
+#define INVALID_SOCKET -1
+
+#endif /* HEADERS_H */
diff --git a/ap/app/zte_ping/readme.txt b/ap/app/zte_ping/readme.txt
new file mode 100755
index 0000000..904f837
--- /dev/null
+++ b/ap/app/zte_ping/readme.txt
@@ -0,0 +1,17 @@
+pingµÄID¹Ì¶¨Îª0x7777£¬ÄÚºËͨ¹ýËüʶ±ð¡£

+

+const struct option long_options[] =

+{

+

+{"ipv4",             no_argument, NULL, '4'},

+//{"ipv6",             no_argument, NULL, '6'},

+{"size",       required_argument, NULL, 'l'}, // icmp data²¿·ÖµÄ³¤¶È, ĬÈÏ800

+{"pingcount",  required_argument, NULL, 'c'}, // pingµÄ´ÎÊý£¬Ä¬ÈÏ100´Î

+{"itemcount",  required_argument, NULL, 'n'}, // ¼Ç¼µÄʱ¼ä½Úµã¸öÊý£¬Èç¹û²»¹»´òÓ¡Òì³£ºóÍ˳ö£¬Ä¬ÈÏ20¸ö

+{"timeout",    required_argument, NULL, 'w'}, // ÿ´ÎpingÍêµÈ´ýreplyµÄʱ¼ä£¬Ä¬ÈÏ4s

+{"interval",   required_argument, NULL, 'i'}, // Á½´ÎpingµÄ¼ä¸ô£¬ÓÐreply 1s·¢ÏÂÒ»¸ö£¬Ã»reply 4sºó·¢ÏÂÒ»¸ö

+{"unstopped",        no_argument, NULL, 't'}, // ÎÞÊýÂÖ100´Î£¬²»Í£µØÅÜ

+

+

+{0, 0, 0, 0}

+};
\ No newline at end of file
diff --git a/ap/app/zte_ping/runner.c b/ap/app/zte_ping/runner.c
new file mode 100755
index 0000000..45e1b31
--- /dev/null
+++ b/ap/app/zte_ping/runner.c
@@ -0,0 +1,732 @@
+
+#include "headers.h"
+#include "runner.h"
+#include "util.h"
+#include "zpingp.h"
+#include "settings.h"
+#include <net/if.h>
+#include <netinet/ip_icmp.h>
+#include "softap_api.h"
+
+
+#define LOG_EMERG       0       /* system is unusable */
+#define LOG_ALERT       1       /* action must be taken immediately */
+#define LOG_CRIT        2       /* critical conditions */
+#define LOG_ERR         3       /* error conditions */
+#define LOG_WARNING     4       /* warning conditions */
+#define LOG_NOTICE      5       /* normal but significant condition */
+#define LOG_INFO        6       /* informational */
+#define LOG_DEBUG       7
+
+#define DEFAULT_IP_ICMP_SIZE 1500
+#define DEFAULT_ICMP_SIZE 1480
+#define DEFAULT_ICMP_DATA_SIZE 1472
+
+#define IPHDR_MINLEN 20
+
+#define DEV_NAME_LEN 32
+#define MAX_MARK_NUM 45
+
+u_int16_t id = 0;
+u_int16_t last_seq_send = 0;
+u_int16_t last_seq_recv = 0;
+
+u_int16_t send_num = 0;
+u_int16_t recv_num = 0;
+
+int pingcount = 100;
+
+int16_t myid = 0; // 0x7777
+
+int delayoutput = 0;
+int lostoutput = 0;
+
+int maxwaitnum = 0;
+
+u_int32_t labels[MAX_MARK_NUM];
+int lost_count[MAX_MARK_NUM];
+
+enum {
+	DEFDATALEN = 56,
+	MAXIPLEN = 60,
+	MAXICMPLEN = 76,
+	MAXPACKET = 65468,
+	MAX_DUP_CHK = (8 * 128),
+	MAXWAIT = 10,
+	PINGINTERVAL = 1, /* 1 second */
+};
+
+zping_print_t label_string[] = {
+	{CLINET_RECV,     "CLINET_RECV"},
+	{CLINET_SEND,     "CLIENT_SEND"},
+	{SERVER_RECV,     "SERVER_RECV"},
+	{SERVER_SEND,     "SERVER_SEND"},
+
+	{AP_USB_IN,       "AP_USB_IN"},
+	{AP_USB_OUT,      "AP_USB_OUT"},
+	{AP_PS_IN,        "AP_PS_IN"},
+	{AP_PS_OUT,       "AP_PS_OUT"},
+	{AP_WIFI_WAN_IN,  "AP_WIFI_WAN_IN"},
+	{AP_WIFI_WAN_OUT, "AP_WIFI_WAN_OUT"},
+	{AP_WIFI_LAN_IN,  "AP_WIFI_LAN_IN"},
+	{AP_WIFI_LAN_OUT, "AP_WIFI_LAN_OUT"},
+	{AP_ETH_WAN_IN,   "AP_ETH_WAN_IN"},
+	{AP_ETH_WAN_OUT,  "AP_ETH_WAN_OUT"},
+	{AP_ETH_LAN_IN,   "AP_ETH_LAN_IN"},
+	{AP_ETH_LAN_OUT,  "AP_ETH_LAN_OUT"},
+	{AP_PS_EXT1_IN,   "AP_PS_EXT1_IN"},
+	{AP_PS_EXT1_OUT,  "AP_PS_EXT1_OUT"},
+	{AP_PS_EXT2_IN,   "AP_PS_EXT2_IN"},
+	{AP_PS_EXT2_OUT,  "AP_PS_EXT2_OUT"},
+	{AP_PS_EXT3_IN,   "AP_PS_EXT3_IN"},
+	{AP_PS_EXT3_OUT,  "AP_PS_EXT3_OUT"},
+	{AP_PS_EXT4_IN,   "AP_PS_EXT4_IN"},
+	{AP_PS_EXT4_OUT,  "AP_PS_EXT4_OUT"},
+
+	{CP_ETH1_IN,      "CP_ETH1_IN"},
+	{CP_ETH1_OUT,     "CP_ETH1_OUT"},
+	{CP_ETH2_IN,      "CP_ETH2_IN"},
+	{CP_ETH2_OUT,     "CP_ETH2_OUT"},
+	{CP_ETH3_IN,      "CP_ETH3_IN"},
+	{CP_ETH3_OUT,     "CP_ETH3_OUT"},
+	{CP_ETH4_IN,      "CP_ETH4_IN"},
+	{CP_ETH4_OUT,     "CP_ETH4_OUT"},
+	{CP_PS1_IN,       "CP_PS1_IN"},
+	{CP_PS1_OUT,      "CP_PS1_OUT"},
+	{CP_PS2_IN,       "CP_PS2_IN"},
+	{CP_PS2_OUT,      "CP_PS2_OUT"},
+	{CP_PS3_IN,       "CP_PS3_IN"},
+	{CP_PS3_OUT,      "CP_PS3_OUT"},
+	{CP_PS4_IN,       "CP_PS4_IN"},
+	{CP_PS4_OUT,      "CP_PS4_OUT"},
+	{CP_CTRM1_IN,     "CP_CTRM1_IN"},
+	{CP_CTRM1_OUT,    "CP_CTRM1_OUT"},
+	{CP_CTRM2_IN,     "CP_CTRM2_IN"},
+	{CP_CTRM2_OUT,    "CP_CTRM2_OUT"},
+	{CP_CTRM3_IN,     "CP_CTRM3_IN"},
+	{CP_CTRM3_OUT,    "CP_CTRM3_OUT"},
+	{CP_CTRM4_IN,     "CP_CTRM4_IN"},
+	{CP_CTRM4_OUT,    "CP_CTRM4_OUT"},
+
+	{LABEL_NULL, 0}
+};
+
+static void init_and_reset(zping_settings_t *zping_settings)
+{
+	id = 0;
+	last_seq_send = 0;
+	last_seq_recv = 0;
+
+	send_num = 0;
+	recv_num = 0;
+
+	pingcount = zping_settings->pingcount;
+
+	myid = zping_settings->set_id; // 0x7777
+}
+
+static int in_cksum(unsigned short *buf, int sz)
+{
+	int nleft = sz;
+	int sum = 0;
+	unsigned short *w = buf;
+	unsigned short ans = 0;
+
+	while (nleft > 1) {
+		sum += *w++;
+		nleft -= 2;
+	}
+
+	if (nleft == 1) {
+		*(unsigned char *)(&ans) = *(unsigned char *) w;
+		sum += ans;
+	}
+
+	sum = (sum >> 16) + (sum & 0xFFFF);
+	sum += (sum >> 16);
+	ans = ~sum;
+	return ans;
+}
+
+static const char *icmp_type_name(int id)
+{
+	switch (id) {
+	case ICMP_ECHOREPLY:
+		return "Echo Reply";
+	case ICMP_DEST_UNREACH:
+		return "Destination Unreachable";
+	case ICMP_SOURCE_QUENCH:
+		return "Source Quench";
+	case ICMP_REDIRECT:
+		return "Redirect (change route)";
+	case ICMP_ECHO:
+		return "Echo Request";
+	case ICMP_TIME_EXCEEDED:
+		return "Time Exceeded";
+	case ICMP_PARAMETERPROB:
+		return "Parameter Problem";
+	case ICMP_TIMESTAMP:
+		return "Timestamp Request";
+	case ICMP_TIMESTAMPREPLY:
+		return "Timestamp Reply";
+	case ICMP_INFO_REQUEST:
+		return "Information Request";
+	case ICMP_INFO_REPLY:
+		return "Information Reply";
+	case ICMP_ADDRESS:
+		return "Address Mask Request";
+	case ICMP_ADDRESSREPLY:
+		return "Address Mask Reply";
+	default:
+		return "unknown ICMP type";
+	}
+}
+
+char *translate_label(u_int32_t label, char *label_str, int len)
+{
+	if (label_str == NULL)
+		return NULL;
+
+	if (len < DEV_NAME_LEN)
+		return NULL;
+
+	memset(label_str, 0, len);
+
+	int i = 0;
+
+	while (1) {
+		if (label_string[i].label == LABEL_NULL)
+			break;
+		if (label == label_string[i].label) {
+			strcpy(label_str, label_string[i].name);
+			break;
+		}
+		i++;
+	}
+	return label_str;
+}
+
+static int analyse_each_zping_reply(char *buf, u_int16_t recv_seq, const u_int16_t id)
+{
+	zping_hdr_t *zping_hdr;
+	zping_item_t *zping_item, *zping_item_first, *zping_items;
+	zping_pktlost_item_t *zping_pktlost_item, *zping_pktlost_item_first, *zping_pktlost_items;
+	int i, j, lost_count_all = 0;
+	char name[32] = {0};
+	//int i, left, right;
+	//char label_str[DEV_NAME_LEN];
+	//char label_str_temp[DEV_NAME_LEN];
+	//zping_item_t *zping_items;
+	int32_t interval_secs, interval_usecs, prev_interval_secs, prev_interval_usecs, temp_secs, temp_usecs;
+	u_int32_t prev_secs, prev_usecs, first_secs, first_usecs;
+	u_int16_t prev_label = 0xffff;
+	prev_secs = prev_usecs = first_secs = first_usecs = -1;
+	int string_for_label = 0;
+	//u_int32_t prev_label = 0;
+
+	interval_secs = interval_usecs = prev_interval_secs = prev_interval_usecs = temp_secs = temp_usecs = -1;
+
+	if (buf == NULL)
+		return 0;
+
+	zping_hdr = (zping_hdr_t *)buf;
+
+	//zping_print(LOG_ALERT, "\n");
+	//zping_print(LOG_ALERT, "item_count:%d, item_index:%d, seq:%d\n",
+	//zping_hdr->item_count, zping_hdr->item_index, recv_seq);
+
+	if (id == 0) {
+		zping_pktlost_items = (zping_pktlost_item_t *)malloc(zping_hdr->item_index * sizeof(zping_pktlost_item_t));
+	} else {
+		zping_items = (zping_item_t *)malloc(zping_hdr->item_index * sizeof(zping_item_t));
+	}
+
+	if (delayoutput) {
+		if (id == 0) {
+			for (i = 0; i < zping_hdr->item_index; i++) {
+				zping_pktlost_item = (zping_pktlost_item_t *)(buf + sizeof(zping_hdr_t) + sizeof(zping_pktlost_item_t) * i);
+
+				zping_print(LOG_ALERT, " last_seq:%d, label:%d \t", zping_pktlost_item->last_seq, zping_pktlost_item->label);//translate_label(zping_item->label, label_str, 16),
+
+				zping_pktlost_items[i].label = zping_pktlost_item->label;
+				zping_pktlost_items[i].last_seq = zping_pktlost_item->last_seq;
+			}
+			zping_print(LOG_ALERT, "\n");
+		} else {
+			for (i = 0; i < zping_hdr->item_index; i++) {
+				zping_item = (zping_item_t *)(buf + sizeof(zping_hdr_t) + sizeof(zping_item_t) * i);
+
+				for (string_for_label = 0; label_string[string_for_label].label != LABEL_NULL; string_for_label++) {
+					if (label_string[string_for_label].label == zping_item->label)
+					{	
+						strcpy(name,label_string[string_for_label].name);
+						break;
+					}
+				}
+
+				zping_print(LOG_ALERT, "node:%d, %s label: %d, last_seq:%ld \n    secs:%ld, usecs:%ld \n",
+				            i, name, zping_item->label,zping_item->last_seq, zping_item->secs, zping_item->usecs);
+
+				zping_items[i].label = zping_item->label;
+				zping_items[i].last_seq = zping_item->last_seq;
+				zping_items[i].secs = zping_item->secs;
+				zping_items[i].usecs = zping_item->usecs;
+
+				if (prev_label != 0xffff)
+				{ 
+					zping_print(LOG_ALERT, "    delay: secs %d   usecs %d \n",
+					            zping_item->secs - prev_secs, zping_item->usecs - prev_usecs);
+				}
+				
+
+				prev_secs = zping_item->secs;
+				prev_usecs = zping_item->usecs;
+				prev_label = zping_item->label;
+				if (first_secs == -1) 
+				{
+					first_secs = zping_item->secs;
+					first_usecs = zping_item->usecs;
+				}
+			}
+			if (zping_hdr->item_index > 1) {
+				zping_print(LOG_ALERT, "whole time interval:%d secs %d usecs \n \n",
+				            zping_item->secs - first_secs, zping_item->usecs - first_usecs);
+			}
+		}
+	}
+
+	if (lostoutput) {
+		if (id == 0) {
+			zping_pktlost_item_first = (zping_pktlost_item_t *)(buf + sizeof(zping_hdr_t));
+			if (send_num - zping_pktlost_item_first->last_seq > 1) {
+				return -1;
+			}
+			prev_label = zping_pktlost_item_first->label;
+			labels[0] = zping_pktlost_item_first->label;
+			for (i = 1; i < zping_hdr->item_index; i++) {
+				zping_pktlost_item = (zping_pktlost_item_t *)(buf + sizeof(zping_hdr_t) + sizeof(zping_pktlost_item_t) * i);
+
+				labels[i] = zping_pktlost_item->label;
+
+				//zping_print(LOG_ALERT, "label:%d, send_num:%d, zping_item->last_seq:%d\n", zping_item->label, send_num, zping_item->last_seq);
+				if (send_num - zping_pktlost_item->last_seq > 1) {
+					zping_print(LOG_ALERT, "node :%d, between label %d and label %d \n",
+					            i, prev_label, zping_pktlost_item->label);
+
+					lost_count[i]++;
+					if (i > 0) {
+						for (j = 1; j < zping_hdr->item_index; j++) {
+							lost_count_all += lost_count[j];
+						}
+						zping_print(LOG_ALERT, "statistics: ");
+						for (j = 1; j < zping_hdr->item_index; j++) {
+							if (lost_count[j] > 0) {
+								zping_print(LOG_ALERT, "between label %d and label %d, lost count:%d, ", labels[j - 1], labels[j], lost_count[j]);
+								zping_print(LOG_ALERT, " label %d : %s   label %d : %s\n",labels[j - 1],label_string[labels[j - 1]].name,labels[j],label_string[labels[j]].name);
+							}
+						}
+						zping_print(LOG_ALERT, "lost count all:%d\n", lost_count_all);
+					}
+
+					break;
+				}
+				prev_label = zping_pktlost_item->label;
+			}
+		} else {
+			zping_item_first = (zping_item_t *)(buf + sizeof(zping_hdr_t));
+			if (send_num - zping_item_first->last_seq > 1) {
+				return -1;
+			}
+			prev_label = zping_item_first->label;
+			labels[0] = zping_item_first->label;
+			for (i = 1; i < zping_hdr->item_index; i++) {
+				zping_item = (zping_item_t *)(buf + sizeof(zping_hdr_t) + sizeof(zping_item_t) * i);
+
+				labels[i] = zping_item->label;
+
+				//zping_print(LOG_ALERT, "label:%d, send_num:%d, zping_item->last_seq:%d\n", zping_item->label, send_num, zping_item->last_seq);
+				if (send_num - zping_item->last_seq > 1) {
+					zping_print(LOG_ALERT, "node:%d, between label %d and label %d, seq lost between %d and %d\n", i, prev_label, zping_item->label, zping_item->last_seq, send_num);
+
+					lost_count[i]++;
+					if (i > 0) {
+						for (j = 1; j < zping_hdr->item_index; j++) {
+							lost_count_all += lost_count[j];
+						}
+						zping_print(LOG_ALERT, "statistics: ");
+						for (j = 1; j < zping_hdr->item_index; j++) {
+							if (lost_count[j] > 0) {
+								zping_print(LOG_ALERT, "between label %d and label %d, lost count:%d, ", labels[j - 1], labels[j], lost_count[j]);
+							}
+						}
+						zping_print(LOG_ALERT, "lost count all:%d\n", lost_count_all);
+					}
+
+					break;
+				}
+				prev_label = zping_item->label;
+			}
+		}
+	}
+
+	if (id == 0) {
+		free(zping_pktlost_items);
+	} else {
+		free(zping_items);
+	}
+	return 1;
+}
+
+int zping_hdr_init(char *buffer, int len, u_int16_t itemcount, u_int16_t id)
+{
+	zping_hdr_t *zping_hdr;
+	int item_size = 0;
+	if (len < sizeof(zping_hdr_t))
+		return 0;
+	zping_hdr = (zping_hdr_t*)buffer;
+
+	zping_hdr->id = id;
+	zping_hdr->item_count = itemcount;
+	zping_hdr->item_index = 0;
+	zping_hdr->item_index_padding = 0xFFFF;
+	zping_hdr->flags = 0;
+	zping_hdr->flags_padding = 0xFFFF;
+
+	item_size = id == 0 ? sizeof(zping_pktlost_item_t) : sizeof(zping_item_t);
+	if (len - sizeof(zping_hdr_t) < zping_hdr->item_count * item_size)
+		return 0;
+
+	return 1;
+}
+
+void init_all_items(char *buffer, u_int16_t itemcount, const u_int16_t id)
+{
+	int i;
+	zping_item_t *zping_item;
+	zping_pktlost_item_t *zping_pktlost_item;
+
+	if (id == 0) {
+		for (i = 0; i < itemcount; i++) {
+			zping_pktlost_item = (zping_pktlost_item_t *)(buffer + sizeof(zping_hdr_t) + sizeof(zping_pktlost_item_t) * i);
+			zping_pktlost_item->label = 0x0;
+			zping_pktlost_item->label_padding = 0xFFFF;
+			zping_pktlost_item->last_seq = 0x0;
+			zping_pktlost_item->last_seq_padding = 0xFFFF;
+		}
+		return;
+	}
+
+	for (i = 0; i < itemcount; i++) {
+		zping_item = (zping_item_t *)(buffer + sizeof(zping_hdr_t) + sizeof(zping_item_t) * i);
+		zping_item->label = 0x0;
+		zping_item->label_padding = 0xFFFF;
+		zping_item->secs = 0x0;
+		zping_item->secs_padding = 0xFFFFFFFF;
+		zping_item->usecs = 0x0;
+		zping_item->usecs_padding = 0xFFFFFFFF;
+		zping_item->last_seq = 0x0;
+		zping_item->last_seq_padding = 0xFFFF;
+	}
+}
+
+int get_current_item_index(char *buffer)
+{
+	zping_hdr_t *zping_hdr = (zping_hdr_t*)buffer;
+	return zping_hdr->item_index;
+}
+void get_uniform_time(unsigned long * sec ,unsigned long * usec )
+{
+	unsigned long long time_usec = get_time_us();
+	*usec = (unsigned long)time_usec;
+	*sec = (unsigned long)((unsigned long)time_usec/1000000);
+}
+
+int set_send_zping_item(char *buffer, int index, const u_int16_t id)
+{
+	struct timeval tv;
+	zping_hdr_t *zping_hdr = (zping_hdr_t*)buffer;
+	zping_pktlost_item_t *zping_pktlost_item;
+	zping_item_t *zping_item;
+
+	if (id == 0) {
+		zping_pktlost_item = (zping_pktlost_item_t *)(buffer + sizeof(zping_hdr_t) + sizeof(zping_pktlost_item_t) * (index - 1));
+		zping_pktlost_item->label = CLINET_SEND;
+		zping_pktlost_item->label_padding = 0xFFFF;
+		zping_pktlost_item->last_seq = last_seq_send;
+	} else {
+		zping_item = (zping_item_t *)(buffer + sizeof(zping_hdr_t) + sizeof(zping_item_t) * (index - 1));
+		zping_item->label = CLINET_SEND;
+		zping_item->label_padding = 0xFFFF;
+		zping_item->secs_padding = 0xFFFFFFFF;
+		zping_item->usecs_padding = 0xFFFFFFFF;
+		//gettimeofday(&tv, NULL);
+		//zping_item->secs = tv.tv_sec;
+		//zping_item->usecs = tv.tv_usec;
+		get_uniform_time(&zping_item->secs,&zping_item->usecs);
+		zping_item->last_seq = last_seq_send;
+	}
+
+	zping_hdr->item_index++;
+	return 1;
+}
+
+int set_recv_zping_item(char *buffer, int index, const u_int16_t id)
+{
+	struct timeval tv;
+	zping_hdr_t *zping_hdr = (zping_hdr_t*)buffer;
+	zping_pktlost_item_t *zping_pktlost_item;
+	zping_item_t *zping_item;
+	if (id == 0) {
+		zping_pktlost_item = (zping_pktlost_item_t *)(buffer + sizeof(zping_hdr_t) + sizeof(zping_pktlost_item_t) * (index - 1));
+		zping_pktlost_item->label_padding = 0xFFFF;
+		zping_pktlost_item->last_seq = last_seq_recv;
+	} else {
+		zping_item = (zping_item_t *)(buffer + sizeof(zping_hdr_t) + sizeof(zping_item_t) * (index - 1));
+		zping_item->label = CLINET_RECV;
+		zping_item->label_padding = 0xFFFF;
+		zping_item->secs_padding = 0xFFFFFFFF;
+		zping_item->usecs_padding = 0xFFFFFFFF;
+
+		//gettimeofday(&tv, NULL);
+		//zping_item->secs = tv.tv_sec;
+		//zping_item->usecs = tv.tv_usec;
+		get_uniform_time(&zping_item->secs,&zping_item->usecs);
+		zping_item->last_seq = last_seq_recv;
+	}
+	zping_hdr->item_index++;
+	return 1;
+}
+
+static int unpack4(char *buf, int sz, struct sockaddr_in *from, const u_int16_t id)
+{
+	//zping_print(LOG_ALERT, "unpack4 enter\n");
+	struct icmp *icmppkt;
+	struct iphdr *iphdr;
+	u_int16_t recv_seq;
+
+	iphdr = (struct iphdr *) buf;
+	icmppkt = (struct icmp *)(buf + (iphdr->ihl << 2));
+
+	set_recv_zping_item(icmppkt->icmp_data, get_current_item_index(icmppkt->icmp_data) + 1, id);
+	recv_seq = ntohs(icmppkt->icmp_seq);
+
+	recv_num++;
+
+	return analyse_each_zping_reply(icmppkt->icmp_data, recv_seq, id);
+	/*
+	if (sz >= ICMP_MINLEN + sizeof(uint32_t)) // todo
+			tp = (uint32_t *) icmppkt->icmp_data;
+		unpack_tail(sz, tp,
+			inet_ntoa(*(struct in_addr *) &from->sin_addr.s_addr),
+			recv_seq, iphdr->ttl);
+	*/
+	//return 1;
+}
+
+static int zping_validate(char *buf, int sz, int send_icmp_data_size)
+{
+	struct icmp *icmppkt;
+	struct iphdr *iphdr;
+	int hlen;
+
+	/* discard if too short */
+	if (sz < (IPHDR_MINLEN + ICMP_MINLEN + send_icmp_data_size))
+		return 0;
+
+	/* check IP header */
+	iphdr = (struct iphdr *) buf;
+	hlen = iphdr->ihl << 2;
+	sz -= hlen;
+	icmppkt = (struct icmp *)(buf + hlen);
+	if (ntohs(icmppkt->icmp_id) != myid)
+		return 0;				/* not our ping */
+
+	if (icmppkt->icmp_type == ICMP_ECHOREPLY) {
+
+	} else if (icmppkt->icmp_type != ICMP_ECHO) {
+		zping_print(LOG_ALERT, "warning: got ICMP %d (%s)",
+		            icmppkt->icmp_type,
+		            icmp_type_name(icmppkt->icmp_type));
+		return 0;
+	}
+	return 1;
+}
+
+void sendping4(zping_settings_t *zping_settings)
+{
+
+}
+
+void ping4(zping_settings_t *zping_settings)
+{
+	struct sockaddr_in pingaddr;
+	int ret;
+	int data_size, icmp_size;
+	int pingsock;
+	int sockopt;
+	struct timeval tv, start_tv, end_tv;
+
+	struct icmp *icmp_pkt;
+	char packet[DEFAULT_IP_ICMP_SIZE];
+	char *icmp_data_zping;
+
+	struct sockaddr_in from;
+	socklen_t fromlen = sizeof(from);
+	int c;
+	int n = 1;
+	int mark = 0;
+	int recv_wait_num = 0;
+
+	memset(lost_count, 0, MAX_MARK_NUM * sizeof(int));
+	memset(labels, 0, MAX_MARK_NUM * sizeof(int));
+
+	data_size = zping_settings->size;
+
+	pingsock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); /* 1 == ICMP */
+	FAIL_errno(pingsock < 0, "sock creat failed");
+
+	/* set recv buf (needed if we can get lots of responses: flood ping,
+	 * broadcast ping etc) */
+	sockopt = (DEFDATALEN * 2) + 7 * 1024; /* giving it a bit of extra room */
+	setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt));
+
+	tv.tv_sec = zping_settings->timeout == 0 ? 4 : zping_settings->timeout;
+	tv.tv_usec = 0;
+	setsockopt(pingsock, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv, sizeof(struct timeval));
+
+another_round:
+	init_and_reset(zping_settings);
+//    zping_print(LOG_ALERT, "\nround %d starts\n", n++);
+	while (1) {
+		if (pingcount != 0 && send_num >= pingcount) {
+			goto out; 
+		}
+
+		icmp_size = data_size + ICMP_MINLEN;
+
+		icmp_pkt = (struct icmp *) packet;
+		memset(icmp_pkt, 0, icmp_size);
+		icmp_pkt->icmp_type = ICMP_ECHO;
+		icmp_pkt->icmp_seq = htons(send_num); /* don't ++ here, it can be a macro */
+		icmp_pkt->icmp_id = htons(myid); // no need to do htons if it's 0x7777
+		//icmp_pkt->icmp_cksum = in_cksum((unsigned short *)icmp_pkt, icmp_size);
+
+		icmp_data_zping = (char *)(icmp_pkt->icmp_data);
+
+		zping_hdr_init(icmp_data_zping, data_size, zping_settings->itemcount, zping_settings->set_id);
+
+		init_all_items(icmp_data_zping, zping_settings->itemcount, zping_settings->set_id);
+
+		//gettimeofday(&tv, NULL);
+
+		set_send_zping_item(icmp_data_zping, 1, zping_settings->set_id);
+
+		icmp_pkt->icmp_cksum = in_cksum((unsigned short *)icmp_pkt, icmp_size);
+
+		gettimeofday(&start_tv, NULL);
+
+		ret = sendto(pingsock, icmp_pkt, icmp_size, 0,
+		             (struct sockaddr *)&zping_settings->zping_sockaddr, sizeof(zping_settings->zping_sockaddr));
+
+		if (mark == 0) {
+			system("cat /proc/uptime  1>/dev/console 2>&1");
+			mark = 1;
+		}
+		FAIL_errno(ret < 0, "sock sendto failed");
+//zping_print(LOG_ALERT, "ping4 sendto\n");
+
+
+recv_reply:
+		/* listen for replies */
+		while (1) {
+
+			memset(icmp_pkt, 0, icmp_size);
+			c = recvfrom(pingsock, packet, DEFAULT_IP_ICMP_SIZE, 0, (struct sockaddr *)&from, &fromlen);
+			//zping_print(LOG_ALERT, "try recvfrom\n");
+			if (c < 0) {
+				//zping_print(LOG_ALERT, "recvfrom error\n");
+				if (errno == EINTR)
+					continue;
+				else {
+					//FAIL_errno(1, "sock recvfrom failed");
+					zping_print(LOG_ALERT, "recvfrom error errno=%d \n",errno);
+					WARN_errno(1, "sock recvfrom failed");
+					recv_wait_num++;
+					if (recv_wait_num >= maxwaitnum)
+						break;
+					//goto out;
+				}
+			} else {
+				//zping_print(LOG_ALERT, "recvfrom received something len:%d\n", c);
+
+				if (zping_validate(packet, c, data_size) == 0) {
+					zping_print(LOG_ALERT, "recvfrom received something we don't need\n");
+					continue;
+				} else {
+					if (mark == 1) {
+						system("cat /proc/uptime  1>/dev/console 2>&1");
+						mark = 2;
+					}
+					ret = unpack4(packet, c, &from, zping_settings->set_id);
+					if (ret == -1) {
+						continue;
+					} else {
+						last_seq_recv = send_num;
+						break;
+					}
+				}
+				/*
+				if(c < icmp_size)
+				{
+				    zping_print(LOG_ALERT, "recvfrom len < icmp_size");
+				    goto out; // think more
+				}
+
+				if(unpack4(packet, c, &from, data_size))
+				{
+				    break;
+				}
+				*/
+			}
+
+		}
+
+		last_seq_send = send_num;
+		send_num++;
+
+		if (pingcount != 0 && send_num > pingcount) {
+			break;
+		} else {
+			gettimeofday(&end_tv, NULL);
+			if (end_tv.tv_sec - start_tv.tv_sec < zping_settings->interval) {
+				sleep(zping_settings->interval - end_tv.tv_sec + start_tv.tv_sec);
+			}
+		}
+	}
+	
+out:
+
+	if (zping_settings->unstopped) {
+		goto another_round;
+	}
+
+
+	close(pingsock);
+	pingsock = -1;
+}
+
+static void ping(zping_settings_t *zping_settings)
+{
+	zping_print(LOG_ALERT, "PING %s", zping_settings->address_str);
+	zping_print(LOG_ALERT, ": %d data bytes\n", zping_settings->size);
+
+	ping4(zping_settings); // ping6 is to be on the way if needed
+}
+
+void start_run(zping_settings_t *zping_settings)
+{
+	delayoutput = zping_settings->delayoutput;
+	lostoutput = zping_settings->lostoutput;
+	maxwaitnum = zping_settings->maxwaitnum;
+	ping(zping_settings);
+}
diff --git a/ap/app/zte_ping/runner.h b/ap/app/zte_ping/runner.h
new file mode 100755
index 0000000..5ffc52a
--- /dev/null
+++ b/ap/app/zte_ping/runner.h
@@ -0,0 +1,20 @@
+
+#ifndef RUNNER_H
+#define RUNNER_H
+
+#include <syslog.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/file.h>
+#include "settings.h"
+#include "netapi.h"
+#include "softap_api.h"
+void start_run(zping_settings_t *zping_settings);
+
+#define zping_print(LEVEL,...) do { printf(__VA_ARGS__); \
+						syslog(LEVEL,__VA_ARGS__);} while(0)
+
+
+#endif // RUNNER_H
diff --git a/ap/app/zte_ping/settings.h b/ap/app/zte_ping/settings.h
new file mode 100755
index 0000000..d972a2f
--- /dev/null
+++ b/ap/app/zte_ping/settings.h
@@ -0,0 +1,44 @@
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include "headers.h"
+
+#include "socketHelper.h"
+
+// server/client mode
+typedef enum {
+	zMode_Unknown = 0,
+	zMode_Server,
+	zMode_Client
+} zMode_t;
+
+// tcp/udp type
+typedef enum {
+	zType_Unknown = 0,
+	zType_Tcp,
+	zType_Udp
+} sock_type_t;
+
+typedef struct {
+	int ip_type; // 0:ipv4,  1:ipv6
+
+	char address_str[64];
+	zping_sockaddr_t zping_sockaddr;
+
+	int pingcount;
+	int timeout;
+	int interval;
+
+	u_int16_t itemcount;// max item num, default is 10
+
+	u_int32_t size; // packet data size
+
+	int unstopped;
+	int delayoutput;
+	int lostoutput;
+
+	int maxwaitnum;
+	u_int16_t set_id;
+} zping_settings_t;
+
+#endif // SETTINGS_H
diff --git a/ap/app/zte_ping/socketHelper.c b/ap/app/zte_ping/socketHelper.c
new file mode 100755
index 0000000..098004e
--- /dev/null
+++ b/ap/app/zte_ping/socketHelper.c
@@ -0,0 +1,132 @@
+
+#include "socketHelper.h"
+#include "util.h"
+
+void close_one_socket(int sock)
+{
+	int ret;
+	if (sock != INVALID_SOCKET) {
+		ret = close(sock);
+		WARN_errno(ret == SOCKET_ERROR, "close socket failed");
+		sock = INVALID_SOCKET;
+	}
+}
+
+void SockAddr_setHostname(const char* inHostname, zping_sockaddr_t *inSockAddr)
+{
+	int rc = inet_pton(AF_INET, inHostname,
+	                   (void*) & (((struct sockaddr_in*)inSockAddr)->sin_addr));
+	inSockAddr->sin_family = AF_INET;
+	if (rc != 1) {
+		fprintf(stderr, "invalid address: %s\n", inHostname);
+		exit(1);
+	}
+}
+
+int setsock_tcp_windowsize(int inSock, int inTCPWin, int inSend)
+{
+#ifdef SO_SNDBUF
+	int rc;
+	int newTCPWin;
+
+	assert(inSock >= 0);
+
+	if (inTCPWin > 0) {
+
+#ifdef TCP_WINSHIFT
+
+		/* UNICOS requires setting the winshift explicitly */
+		if (inTCPWin > 65535) {
+			int winShift = 0;
+			int scaledWin = inTCPWin >> 16;
+			while (scaledWin > 0) {
+				scaledWin >>= 1;
+				winShift++;
+			}
+
+			/* set TCP window shift */
+			rc = setsockopt(inSock, IPPROTO_TCP, TCP_WINSHIFT,
+			                (char*) &winShift, sizeof(winShift));
+			if (rc < 0) {
+				return rc;
+			}
+
+			/* Note: you cannot verify TCP window shift, since it returns
+			 * a structure and not the same integer we use to set it. (ugh) */
+		}
+#endif /* TCP_WINSHIFT  */
+
+#ifdef TCP_RFC1323
+		/* On AIX, RFC 1323 extensions can be set system-wide,
+		 * using the 'no' network options command. But we can also set them
+		 * per-socket, so let's try just in case. */
+		if (inTCPWin > 65535) {
+			/* enable RFC 1323 */
+			int on = 1;
+			rc = setsockopt(inSock, IPPROTO_TCP, TCP_RFC1323,
+			                (char*) &on, sizeof(on));
+			if (rc < 0) {
+				return rc;
+			}
+		}
+#endif /* TCP_RFC1323 */
+
+		if (!inSend) {
+			/* receive buffer -- set
+			 * note: results are verified after connect() or listen(),
+			 * since some OS's don't show the corrected value until then. */
+			newTCPWin = inTCPWin;
+			rc = setsockopt(inSock, SOL_SOCKET, SO_RCVBUF,
+			                (char*) &newTCPWin, sizeof(newTCPWin));
+		} else {
+			/* send buffer -- set
+			 * note: results are verified after connect() or listen(),
+			 * since some OS's don't show the corrected value until then. */
+			newTCPWin = inTCPWin;
+			rc = setsockopt(inSock, SOL_SOCKET, SO_SNDBUF,
+			                (char*) &newTCPWin, sizeof(newTCPWin));
+		}
+		if (rc < 0) {
+			return rc;
+		}
+	}
+#endif /* SO_SNDBUF */
+
+	return 0;
+} /* end setsock_tcp_windowsize */
+
+const char warn_mss_fail[] = "\
+WARNING: attempt to set TCP maxmimum segment size to %d failed.\n\
+Setting the MSS may not be implemented on this OS.\n";
+
+const char warn_mss_notset[] =
+    "WARNING: attempt to set TCP maximum segment size to %d, but got %d\n";
+
+void setsock_tcp_mss(int inSock, int inMSS)
+{
+#ifdef TCP_MAXSEG
+	int rc;
+	int newMSS;
+	int len;
+
+	assert(inSock != INVALID_SOCKET);
+
+	if (inMSS > 0) {
+		/* set */
+		newMSS = inMSS;
+		len = sizeof(newMSS);
+		rc = setsockopt(inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS,  len);
+		if (rc == SOCKET_ERROR) {
+			fprintf(stderr, warn_mss_fail, newMSS);
+			return;
+		}
+
+		/* verify results */
+		rc = getsockopt(inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS, &len);
+		WARN_errno(rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG");
+		if (newMSS != inMSS) {
+			fprintf(stderr, warn_mss_notset, inMSS, newMSS);
+		}
+	}
+#endif
+} /* end setsock_tcp_mss */
diff --git a/ap/app/zte_ping/socketHelper.h b/ap/app/zte_ping/socketHelper.h
new file mode 100755
index 0000000..5dde0bb
--- /dev/null
+++ b/ap/app/zte_ping/socketHelper.h
@@ -0,0 +1,24 @@
+
+#ifndef SOCKET_HELPER_H
+#define SOCKET_HELPER_H
+
+#include "headers.h"
+
+/*
+typedef union
+{
+	struct sockaddr_in sockaddr;
+	struct sockaddr_in6 sockaddr6;
+} zperf_sockaddr_t;
+*/
+typedef struct sockaddr_in zping_sockaddr_t;
+
+void close_one_socket(int sock);
+
+void SockAddr_setHostname(const char* inHostname, zping_sockaddr_t *inSockAddr) ;
+
+int setsock_tcp_windowsize(int inSock, int inTCPWin, int inSend);
+
+void setsock_tcp_mss(int inSock, int inMSS);
+
+#endif
diff --git a/ap/app/zte_ping/util.h b/ap/app/zte_ping/util.h
new file mode 100755
index 0000000..42f81b0
--- /dev/null
+++ b/ap/app/zte_ping/util.h
@@ -0,0 +1,58 @@
+
+#ifndef UTIL_H
+#define UTIL_H
+
+void warn(const char *inMessage, const char *inFile, int inLine);
+void warn_errno(const char *inMessage, const char *inFile, int inLine);
+
+#define FAIL(cond, msg)             \
+  do {                                          \
+    if (cond) {                               \
+      warn(msg, __FILE__, __LINE__);          \
+      exit(1);                                \
+    }                                           \
+  } while(0)
+
+#define FAIL_errno(cond, msg)       \
+  do {                                          \
+    if (cond) {                               \
+      warn_errno(msg, __FILE__, __LINE__);    \
+      exit(1);                                \
+    }                                           \
+  } while( 0 )
+
+#define WARN( cond, msg )                       \
+  do {                                          \
+    if ( cond ) {                               \
+      warn( msg, __FILE__, __LINE__ );          \
+    }                                           \
+  } while( 0 )
+
+#define WARN_errno( cond, msg )                 \
+  do {                                          \
+    if ( cond ) {                               \
+      warn_errno( msg, __FILE__, __LINE__ );    \
+    }                                           \
+  } while( 0 )
+
+/* -------------------------------------------------------------------
+ * delete macro
+ * ------------------------------------------------------------------- */
+/*
+#define DELETE_PTR( ptr )                       \
+ do {                                          \
+   if ( ptr != NULL ) {                        \
+     delete ptr;                               \
+     ptr = NULL;                               \
+   }                                           \
+ } while( false )
+
+#define DELETE_ARRAY( ptr )                     \
+ do {                                          \
+   if ( ptr != NULL ) {                        \
+     delete [] ptr;                            \
+     ptr = NULL;                               \
+   }                                           \
+ } while( false )
+*/
+#endif /* UTIL_H */
diff --git a/ap/app/zte_ping/zping.c b/ap/app/zte_ping/zping.c
new file mode 100755
index 0000000..b9c11fc
--- /dev/null
+++ b/ap/app/zte_ping/zping.c
@@ -0,0 +1,207 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include "headers.h"
+#include "settings.h"
+#include "runner.h"
+#include "socketHelper.h"
+#include "zpingp.h"
+#include "softap_log.h"
+
+
+const struct option long_options[] = {
+
+	{"ipv4",             no_argument, NULL, '4'},
+//{"ipv6",             no_argument, NULL, '6'},
+	{"size",       required_argument, NULL, 'l'},
+	{"pingcount",  required_argument, NULL, 'c'},
+	{"itemcount",  required_argument, NULL, 'n'},
+	{"timeout",    required_argument, NULL, 'w'}, // wait "w" seconds for each reply
+	{"interval",   required_argument, NULL, 'i'}, // minimum seconds between two requests
+	{"unstopped",        no_argument, NULL, 't'},
+	{"printall",      	 no_argument, NULL, 'p'},
+	{"lostoutput",       no_argument, NULL, 'o'},
+	{"maxwaitnum", required_argument, NULL, 'u'},
+	{"delaycheck", 		 no_argument, NULL, 'd'},
+	{"help", 		     no_argument, NULL, 'h'},
+
+	{0, 0, 0, 0}
+};
+
+const char short_options[] = "4l:c:n:w:i:tpou:dh";
+
+void sig_handler(int sig)
+{
+	if (sig == SIGINT || sig == SIGTERM) {
+		exit(0);
+	}
+}
+
+
+void init_settings(zping_settings_t *zping_settings)
+{
+	memset(zping_settings, 0, sizeof(zping_settings_t));
+
+	zping_settings->size = 800;
+	zping_settings->itemcount = 20;
+	zping_settings->pingcount = 100;
+	zping_settings->timeout = 4;
+	zping_settings->interval = 1;
+	zping_settings->lostoutput = 1;
+	zping_settings->unstopped = 1;
+}
+
+int main(int argc, char** argv)
+{
+	int c, rc;
+	zping_settings_t zping_settings;
+
+	int item_size = 0;
+
+	struct sigaction sigact;
+	/* // for child pthreads to ignore SIGPIPE
+	    sigset_t signal_mask;
+	    sigemptyset (&signal_mask);
+	    sigaddset (&signal_mask, SIGPIPE);
+	    rc = pthread_sigmask (SIG_BLOCK, &signal_mask, NULL);
+	    if (rc != 0)
+	    {
+	       zping_print(LOG_ALERT, "block sigpipe error\n");
+	    }
+	*/
+
+	sigact.sa_handler = sig_handler;
+	sigact.sa_flags = 0;
+	sigemptyset(&sigact.sa_mask);
+	sigaction(SIGINT, &sigact, NULL);
+	sigaction(SIGTERM, &sigact, NULL);
+
+	/* ignore SIGPIPE */
+	sigact.sa_handler = SIG_IGN;
+	sigact.sa_flags = 0;
+	sigemptyset(&sigact.sa_mask);
+	sigaction(SIGPIPE, &sigact, NULL);
+
+	//pthread_t tid = pthread_self();
+	//zping_print(LOG_ALERT, "main pthread id:%lu \n",tid);
+
+	//memset(&zperf_settings, 0, sizeof(zperf_settings_t));
+	init_settings(&zping_settings);
+
+	while ((c = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) {
+		//test = 1;
+		zping_print(LOG_ALERT, "option %c\n", c);
+		switch (c) {
+		case '4':
+			zping_settings.ip_type = 0;
+			break;
+
+		case 'l':
+			zping_settings.size = atoi(optarg);
+			break;
+
+		case 'c':
+			zping_settings.pingcount = atoi(optarg);
+			zping_settings.unstopped = 0;
+			break;
+
+		case 'n':
+			zping_settings.itemcount = atoi(optarg);
+			break;
+
+		case 'w':
+			zping_settings.timeout = atoi(optarg);
+			break;
+
+		case 'i':
+			zping_settings.interval = atoi(optarg);
+			break;
+
+		case 't':
+			zping_settings.unstopped = 1;
+			break;
+
+		case 'p':
+			zping_settings.delayoutput = 1;
+			break;
+
+		case 'o':
+			zping_settings.lostoutput = 1;
+			break;
+
+		case 'u':
+			zping_settings.maxwaitnum = atoi(optarg);
+			break;
+
+		case 'd':
+			//if (atoi(optarg) == 1 || atoi(optarg) == 0)
+			//	zping_settings.set_id = atoi(optarg);
+			zping_settings.set_id = 1;
+			zping_settings.delayoutput = 1;
+			break;
+
+		case 'h':
+			printf("zping ip_addr [options] \n");
+			printf("options: \n");			
+			printf("-d  		delay check \n");
+			printf("-c num  	ping num\n");
+			printf("-l size  	ping size\n");
+			printf("-p  		print every packet\n");	
+			goto out;			
+
+		case '?':
+			break;
+
+		default:
+			zping_print(LOG_ALERT,  "?? getopt returned character code 0%o ??\n", c);
+			break;
+		}
+	}
+
+	if (argc <= 1) {
+		zping_print(LOG_ALERT, "zping -h for usage \n");
+		goto out;
+	}
+
+	strcpy(zping_settings.address_str, argv[optind]);
+	SockAddr_setHostname(zping_settings.address_str, &zping_settings.zping_sockaddr);
+
+	//zping_print(LOG_ALERT, "zping_settings.address_str:%s, %x\n", zping_settings.address_str,
+	//    ((struct sockaddr_in*)&zping_settings.zping_sockaddr)->sin_addr.s_addr);
+
+	if (zping_settings.size > 1472) {
+		zping_print(LOG_ALERT, "size should not be greater than 1472\n");
+		goto out;
+	}
+
+	item_size = zping_settings.set_id == 0 ? sizeof(zping_pktlost_item_t) : sizeof(zping_item_t);
+	if (zping_settings.size < sizeof(zping_hdr_t) + zping_settings.itemcount * item_size) {
+		zping_print(LOG_ALERT, "%d bytes is not enough to contain %d items, at least %d bytes are needed\n",
+		            zping_settings.size, zping_settings.itemcount,
+		            sizeof(zping_hdr_t) + zping_settings.itemcount * item_size);
+		goto out;
+	}
+	if(zping_settings.set_id)		
+		zping_print(LOG_ALERT, "work type:  deley check \n");
+	else
+		zping_print(LOG_ALERT, "work type:  loss check \n");
+	zping_print(LOG_ALERT, "ping size: %d \n",zping_settings.size);
+	zping_print(LOG_ALERT, "node num: %d \n",zping_settings.itemcount);	
+	if(zping_settings.unstopped)
+		zping_print(LOG_ALERT, "ping num: endless \n");
+	else
+		zping_print(LOG_ALERT, "ping num: %d \n",zping_settings.pingcount);
+	zping_print(LOG_ALERT, "wait time: %d \n",zping_settings.timeout);	
+	
+	start_run(&zping_settings);
+
+	//thread_start(&zperf_settings);
+
+	//thread_join(&zperf_settings);
+
+	//zping_print(LOG_ALERT, "Hello World\n");
+	//getchar();
+	//all done !
+out:
+	return 0;
+}
+
diff --git a/ap/app/zte_ping/zpingp.h b/ap/app/zte_ping/zpingp.h
new file mode 100755
index 0000000..cdb4516
--- /dev/null
+++ b/ap/app/zte_ping/zpingp.h
@@ -0,0 +1,121 @@
+#ifndef __ZPING_H__
+#define __ZPING_H__
+
+#include "headers.h"
+
+typedef unsigned int u_int;
+
+typedef signed char int8_t;
+typedef unsigned char u_int8_t;
+typedef signed short int16_t;
+typedef unsigned short u_int16_t;
+typedef signed int int32_t;
+typedef unsigned int u_int32_t;
+typedef signed long long int64_t;
+typedef unsigned long long u_int64_t;
+
+#define ZPING_EXCLUDE 0x01
+
+#define DEFAULT_BUFFER_SIZE 1460
+
+#define DEFAULT_BUFFER_COPY_TIMEOUT 3
+
+typedef enum {
+	//pc²àʹÓ÷¶Î§0~31
+	LABEL_NULL = 0,
+
+	CLINET_RECV,
+	CLINET_SEND,
+	SERVER_RECV,
+	SERVER_SEND,
+
+	//AP²àÍø¿ÚÒÔ32¿ªÊ¼£¬²»Í¬µÄºË²ÉÓò»Í¬µÄÊý¾Ý¶Î¶¨Òå,32~63
+	AP_USB_IN = 32,
+	AP_USB_OUT,
+	AP_PS_IN,
+	AP_PS_OUT,
+	AP_WIFI_WAN_IN,
+	AP_WIFI_WAN_OUT,
+	AP_WIFI_LAN_IN,
+	AP_WIFI_LAN_OUT,
+	AP_ETH_WAN_IN,
+	AP_ETH_WAN_OUT,
+	AP_ETH_LAN_IN,
+	AP_ETH_LAN_OUT,
+	AP_PS_EXT1_IN,
+	AP_PS_EXT1_OUT,
+	AP_PS_EXT2_IN,
+	AP_PS_EXT2_OUT,
+	AP_PS_EXT3_IN,
+	AP_PS_EXT3_OUT,
+	AP_PS_EXT4_IN,
+	AP_PS_EXT4_OUT,
+
+	//CP²àÍø¿ÚÒÑ64¿ªÊ¼.64~95
+	CP_ETH1_IN = 64,
+	CP_ETH1_OUT,
+	CP_ETH2_IN,
+	CP_ETH2_OUT,
+	CP_ETH3_IN,
+	CP_ETH3_OUT,
+	CP_ETH4_IN,
+	CP_ETH4_OUT,
+	CP_PS1_IN,
+	CP_PS1_OUT,
+	CP_PS2_IN,
+	CP_PS2_OUT,
+	CP_PS3_IN,
+	CP_PS3_OUT,
+	CP_PS4_IN,
+	CP_PS4_OUT,
+	CP_CTRM1_IN,
+	CP_CTRM1_OUT,
+	CP_CTRM2_IN,
+	CP_CTRM2_OUT,
+	CP_CTRM3_IN,
+	CP_CTRM3_OUT,
+	CP_CTRM4_IN,
+	CP_CTRM4_OUT,
+} zping_label;
+
+typedef struct {
+	zping_label label;
+	char name[32];
+} zping_print_t;
+
+
+#pragma pack(push)
+#pragma pack(1)
+typedef struct { // 4 bytes align
+	u_int16_t id; // useless in this case, use id in the icmp header instead
+	u_int16_t item_count;
+	u_int16_t item_index;
+	u_int16_t item_index_padding;
+	u_int16_t flags;
+	u_int16_t flags_padding;
+} zping_hdr_t;
+
+typedef struct { // 4 bytes align
+	u_int16_t label;
+	u_int16_t label_padding;
+
+	u_int32_t secs;
+	u_int32_t secs_padding;
+
+	u_int32_t usecs;
+	u_int32_t usecs_padding;
+
+	u_int16_t last_seq;
+	u_int16_t last_seq_padding;
+} zping_item_t ;
+
+typedef struct { // 4 bytes align
+	u_int16_t label;
+	u_int16_t label_padding;
+
+	u_int16_t last_seq;
+	u_int16_t last_seq_padding;
+} zping_pktlost_item_t;
+#pragma pack(pop)
+
+#endif /* __ZPING_H__ */