www.pudn.com > TCPmodbushy.rar > TCPIPmodbus.c


/****************************************************************************** 
 * Project     : t_box 
 * Module Name : TCPIPmodbus.C 
 * CPU Type    : C8051F340 
 * 
 * Description : 
 * 
 * History        Author     Version       Comment 
 * 2006.10.22       HY       V0.0         Original version 
 * 
 * Copyright (C) 2006 HY. All rights reserved. 
 ******************************************************************************/ 
#include   "o:\sysdef.h" 
#include	"modbus.h" 
#include  
#include  
 
uchar	data	ERRtype; 
uchar 	idata	affair_head_info[16]; 
/****************************************************************************** 
* TCP/IP modbus analys 
******************************************************************************/ 
void TCP_MODBUS_analyse( uchar head ) 
{ 
	uint  Len; 
	uchar function; 
	uchar xdata *pd; 
	uchar subOP; 
	uchar offset; 
	uint  Modbus_Identifier; 
 
	if( ( (memory[head].tag) & 0x40 ) == SERVE_TRANS_MESSAGE ) 
	{ 
		serve_trans_message_process(head); 
		return; 
	} 
	if( memory[head].space[0] == UDP_PROTOCOL ) 
	{ 
		offset = UDP_DATA_STR; 
	}	 
	else 
	{ 
		offset = TCP_DATA_STR; 
	} 
	// Copy	TCPModbusHead into current deal CMD( Include 'Device Station(1)' ) 
	for( Len=0; Len<(offset+TCPMODBUS_LEN+1); Len++ ) 
	{ 
		affair_head_info[Len] = memory[head].space[Len]; 
	} 
	if(affair_head_info[0] == TCP_PROTOCOL) 
		affair_head_info[Len] = ( memory[head].TCP_connect_num & 0x7F ); 
	pd = &(memory[head].space[offset]); 
	Modbus_Identifier = MAKE_WORD( memory[head].space[offset], memory[head].space[offset+1] ); 
	function = memory[head].space[offset+TCPMODBUS_LEN+1];	// TCPMODBUS_HEAD:DeviceStation:CMD 
	subOP = memory[head].space[offset+TCPMODBUS_LEN+1+1];	// TCPMODBUS_HEAD:DeviceStation:CMD:SubCMD 
 
	/* analyse and process extend modbus function*/ 
	switch( function ) 
	{ 
	case LAND_FUNCTION: 
		if( query_Transaction( Modbus_Identifier ) ) 
		{ 
			del_Transaction( Modbus_Identifier ); 
			p2p_cmdOK_process(subOP,pd); 
		} 
		if(subOP == P2PTRANSH) 
		{ 
			ulong dst_ip; 
			uint  dst_port; 
			dst_ip = MAKE_LONG( MAKE_WORD(affair_head_info[1],affair_head_info[2]), 
									MAKE_WORD(affair_head_info[3],affair_head_info[4])); 
			dst_port = MAKE_WORD(affair_head_info[5],affair_head_info[6]); 
			if(net_group_type == CONE_SYMMETRIC) 
				dst_port++; 
			answer_P2Ptransh( dst_ip,dst_port,MAKE_WORD( *pd,*(pd+1) ),MAKE_WORD(affair_head_info[7],affair_head_info[8])); 
		} 
		break; 
	case LAND_FUN_ERR: 
		if( query_Transaction( Modbus_Identifier ) ) 
		{ 
			del_Transaction( Modbus_Identifier ); 
			p2p_cmdERR_process(subOP); 
		} 
		break; 
	case QUERY_IP: 
		switch( subOP ) 
		{ 
		case QUERY_IP_SUBOP: 
       			reply_query_ip( head ); 
			break; 
		case QUERY_IP_ANSWER: 
			if( query_Transaction( Modbus_Identifier ) ) 
			{ 
				ulong IP_value; 
				IP_value = get_receive_ip( head ); 
				add_station_IP( memory[head].space[offset+TCPMODBUS_LEN+1+1+1+3],IP_value );		/*receive query ip response*/ 
				if( (station_IP(CommuBuffer[0]) != ERR) && master_com_flag ) 
				{ 
						switch_message();					/*this port's IP have get,send data use tcp*/ 
				} 
				del_Transaction( Modbus_Identifier ); 
			} 
			break; 
		}							 
		break; 
	case PARAMETER_FUN: 
		switch(subOP) 
		{ 
    	case PARAMETER_QUERY: 
			if( ( (*(pd+9) == (!(CurWorkState & MASTER_NOT_SLAVE)) || *(pd+9) == ALL_TBOX) )   
							&& (!(CurWorkState & MASTER_NOT_SLAVE)) ) 
			{ 
				slave_replay_parameter(NULL); 
			} 
			if(	( (*(pd+9) == ( !(CurWorkState & MASTER_NOT_SLAVE )) || *(pd+9) == ALL_TBOX) ) 
				&& ( CurWorkState & MASTER_NOT_SLAVE ) ) 
			{ 
				master_reply_parameter(NULL); 
			} 
			else 
				*(pd+9) = 0; 
			break; 
		case READ_PARA: 
			if(ERR_chk(pd)) 
				reply_read_OK( head ); 
			else 
				reply_read_ERR(NULL); 
			break; 
		case WRITE_PARA: 
			if(*(pd+12) == (!(CurWorkState & MASTER_NOT_SLAVE))|| *(pd+12) == ALL_TBOX) 
			{ 
			 	if(ERR_chk(pd)) 
			 		reply_write_OK(head); 
			 	else 
					reply_write_ERR(NULL); 
			} 
			break; 
		case ERASURE_FUN: 
			reply_erasure(pd); 
			break; 
		case PARA_AFFIRM: 
			affirm_para(NULL); 
		break; 
		} 
		break; 
	default: 
		//if( !(CurWorkState & SETPARA_NOT_WORK) ) 
			UART_transmitted( head );			/* normal modbus function */ 
		return;									// Queeue space free in 'UART_transmitted()' 
	} 
	free_memb( &(memory[head]) ); 
	//return; 
} 
 
/****************************************************************************** 
* apply land 
******************************************************************************/ 
bit land_apply( ulong sever_ip,uint sever_port,uchar idata *num) 
{ 
	uchar NameAddLen,PasswordLen; 
	uint size;	 
	uchar head,offset; 
	MEMB xdata *pd; 
 
	NameAddLen = GetWordLen( USE_NAME_ADDRESS ); 
	PasswordLen = GetWordLen( USE_PASSWORD_ADDRESS ); 
	 
	// Head + deviceNO + CMD + SubCMD + ADDRESS + PASSWORD 
	size = TCPMODBUS_LEN + 1 + 1 + 1 + NameAddLen + PasswordLen; 
	head = apply_memb( size ); 
	if(head != MEMORY_EER) 
	{ 
		pd = &memory[head]; 
 
		/* Prepare TcpModbus Head */ 
		PrepareHostSenderTcpModbusHead( pd, ( size - TCPMODBUS_LEN ) ); 
		/* device NO */ 
		pd->space[6] = 0x00; 
		/* CMD */ 
		pd->space[7] = LAND_FUNCTION; 
		/* SubCMD */ 
		pd->space[8] = LAND_APPLY; 
 
		offset = 9; 
		pd = WriteMembFromFlash( pd, &offset, USE_NAME_ADDRESS, NameAddLen ); 
		pd = WriteMembFromFlash( pd, &offset, USE_PASSWORD_ADDRESS, PasswordLen ); 
 
/* Need edit */ 
		//UDP_send_data( head, 0xc0A8007F, 502 ); 
		*num = memory[head].space[0]; 
	 	*(num+1) = memory[head].space[1]; 
		UDP_send_data( head, sever_ip, sever_port,UDP_LOCAL_PORT ); 
		return(OK); 
	} 
	else 
	{ 
		return(ERR); 
	} 
} 
 
/******************************************************************************* 
* Para: 	pd:		SAVE TCPMODBUS'HEAD Area  
*			Len:	TCPMODBUS DATA AREA LENGTH 
********************************************************************************/ 
void PrepareHostSenderTcpModbusHead( MEMB xdata *pd, uint Len ) 
{ 
	uint Tmp; 
	Tmp = apply_Transaction(); 
	pd->space[0] = HIGH_BYTE( Tmp ); 
	pd->space[1] = LOW_BYTE( Tmp ); 
	pd->space[2] = 0; 
	pd->space[3] = 0; 
	pd->space[4] = HIGH_BYTE( Len ); 
	pd->space[5] = LOW_BYTE( Len ); 
} 
 
/************************************************************************* 
* Para: 	pd:		SAVE ResponseTCPMODBUS'HEAD Area  
*			Len:	TCPMODBUS DATA AREA LENGTH 
* NOTE:		Include 'DeviceNO' 
*************************************************************************/ 
void PrepareReplyTcpModbusHead( MEMB xdata *pd, uint Len ) 
{ 
	uchar offset; 
	if( affair_head_info[0] ==  UDP_PROTOCOL ) 
		offset = UDP_DATA_STR; 
	else 
		offset = TCP_DATA_STR;	// TCP 
	pd->space[0] = affair_head_info[offset]; 
	pd->space[1] = affair_head_info[offset + 1]; 
	pd->space[2] = affair_head_info[offset + 2]; 
	pd->space[3] = affair_head_info[offset + 3]; 
	pd->space[4] = HIGH_BYTE( Len ); 
	pd->space[5] = LOW_BYTE( Len ); 
	pd->space[6] = affair_head_info[offset+6]; 
} 
 
/******************************************************************************* 
* Send broadcast to get the station's IP 
********************************************************************************/ 
void queryIP( uchar station ) 
{ 
	MEMB xdata *pd; 
	uint Len; 
	uchar head; 
	 
	// TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) + SlaveNo(4); 
	Len = TCPMODBUS_LEN + 1 + 1 + 1 + 4; 
	head = apply_memb( Len ); 
	if( head != MEMORY_EER ) 
	{ 
		pd = &memory[head]; 
		PrepareHostSenderTcpModbusHead( pd, ( Len - TCPMODBUS_LEN ) ); 
 
		// deviceNO(1) 
		pd->space[6] = 0x00; 
		// CMD(1) 
		pd->space[7] = QUERY_IP; 
		// SubCMD(1) 
		pd->space[8] = QUERY_IP_SUBOP; 
		// SlaveNo(4); 
		pd->space[9] = 0; 
		pd->space[10] = 0; 
		pd->space[11] = 0; 
		pd->space[12] = station; 
		UDP_send_data( head,0xFFFFFFFF,502,UDP_LOCAL_PORT);		/*broadcast ip*/ 
	} 
} 
 
/****************************************************************************** 
* reply query ip request(slave) 
******************************************************************************/ 
void reply_query_ip( uchar head ) 
{ 
	uchar station_num; 
	uchar offset; 
 
	if( affair_head_info[0] ==  UDP_PROTOCOL ) 
		offset = UDP_DATA_STR; 
	else 
		offset = TCP_DATA_STR; 
	// DeviceStation(1) + CMD(1) + SunCMD(1) + SlaveStation( DWORD('LowByte') ) 
	station_num = memory[head].space[offset+TCPMODBUS_LEN+1+1+1+3]; 
 
	if( query_equipment_list( station_num ) != ERR ) 
	{ 
		if( !shield_station( station_num ) ) 
		{ 
			uint Len; 
			// TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) + SlaveNo(4); 
			Len = TCPMODBUS_LEN + 1 + 1 + 1 + 4; 
			head = apply_memb( Len ); 
			if( head != MEMORY_EER ) 
			{ 
				// Prepare include deviceNO(1) 
				PrepareReplyTcpModbusHead( &( memory[head] ) , ( Len - TCPMODBUS_LEN ) ); 
				// CMD 
				memory[head].space[7] = QUERY_IP; 
				// SubCMD(1) 
				memory[head].space[8] = QUERY_IP_ANSWER; 
				// SlaveNo(4); 
				memory[head].space[9] = 0; 
				memory[head].space[10] = 0; 
				memory[head].space[11] = 0; 
				memory[head].space[12] = station_num; 
				send_data ( head, affair_head_info ); 
			} 
		} 
	} 
} 
 
/****************************************************************************** 
* master reply parameter query 
*******************************************************************************/ 
void master_reply_parameter( uchar xdata *DATA ) 
{ 
	uchar head; 
	uint  Len; 
	if(!extend_trans_flag) 
	// TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) + TBOX_TYPE(1) 
		Len = TCPMODBUS_LEN + 1 + 1 + 1 + 1; 
	else 
		Len = TCPMODBUS_LEN + 1 + 1 + 1 + 1 + TRANS_COMMAND_LEN; 
	head = apply_memb( Len ); 
	if(head != MEMORY_EER) 
	{ 
		uchar offset; 
		offset = TCPMODBUS_LEN + 1; 
		// Prepare include deviceNO(1) 
		PrepareReplyTcpModbusHead( &( memory[head] ) , ( Len - TCPMODBUS_LEN ) ); 
		if(extend_trans_flag) 
		{ 
			PrepareReplyTransHead( head,( Len - TCPMODBUS_LEN ),DATA); 
			offset = TRANS_COMMAND_LEN+TCPMODBUS_LEN+1; 
		} 
		// CMD 
		memory[head].space[offset] = PARAMETER_FUN; 
		// SubCMD 
		memory[head].space[offset+1] = PARA_QUERY_ANSWER; 
		// TBOX_type 
		memory[head].space[offset+2] = T_BOX_MASTER; 
		if(extend_trans_flag) 
		{ 
			send_to_serve1(head); 
		} 
		else 
			send_data(head,affair_head_info); 
	} 
} 
 
/****************************************************************************** 
*  slave reply parameter query 
******************************************************************************/ 
void slave_replay_parameter( uchar xdata *DATA ) 
{ 
	uint Len; 
	uchar head, SlaveStationNum; 
 
	// Calcuate buffer size 
	SlaveStationNum = Calcuate_SlaveStationNum(); 
	if(!extend_trans_flag) 
	// TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) + TBOX_TYPE(1) + SlaveStationNum 
		Len = TCPMODBUS_LEN + 1 + 1 + 1 + 1 + SlaveStationNum; 
	else 
		Len = TCPMODBUS_LEN + 1 + 1 + 1 + 1 + SlaveStationNum + TRANS_COMMAND_LEN; 
	head = apply_memb( Len ); 
	if( head != MEMORY_EER ) 
	{ 
		uchar i,offset; 
		MEMB xdata *pd; 
		// Prepare include deviceNO(1) 
		PrepareReplyTcpModbusHead( &( memory[head] ) , ( Len - TCPMODBUS_LEN ) ); 
		offset = TCPMODBUS_LEN + 1; 
		if(extend_trans_flag) 
		{ 
			PrepareReplyTransHead( head,( Len - TCPMODBUS_LEN ),DATA); 
			offset = TRANS_COMMAND_LEN+TCPMODBUS_LEN+1; 
		} 
		// CMD 
		memory[head].space[offset] = PARAMETER_FUN; 
		// SubCMD 
		memory[head].space[offset+1] = PARA_QUERY_ANSWER; 
		// TBOX_TYPE 
		memory[head].space[offset+2] = T_BOX_SLAVE; 
		// Slave Station Num 
		memory[head].space[offset+3] = SlaveStationNum; 
		 
		// Fill the slave Station num list 
		offset += 4; 
		pd = &( memory[head] ); 
		for( i=1; ispace[offset] = i; 
				offset++; 
				if( offset == pd->size ) 
				{ 
					pd = pd->link; 
					offset = 0; 
				} 
			} 
		} 
		if(extend_trans_flag) 
			send_to_serve1(head); 
		else 
			send_data(head,affair_head_info); 
	} 
} 
 
/**************************************************************************** 
reply a error read request 
****************************************************************************/ 
void reply_read_ERR( uchar xdata *pd ) 
{ 
	uchar	head; 
	uint	Len; 
	if(!extend_trans_flag) 
		// TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) 
		Len = TCPMODBUS_LEN + 1 + 1 + 1; 
	else 
		Len = TCPMODBUS_LEN + 1 + 1 + 1 + TRANS_COMMAND_LEN; 
	head = apply_memb( Len ); 
	if(head != MEMORY_EER) 
	{ 
		uchar offset; 
		// Prepare include deviceNO(1) 
		PrepareReplyTcpModbusHead( &( memory[head] ) , ( Len - TCPMODBUS_LEN ) ); 
		offset = TCPMODBUS_LEN + 1; 
		if(extend_trans_flag) 
		{ 
			PrepareReplyTransHead( head,( Len - TCPMODBUS_LEN ),pd); 
			offset = TRANS_COMMAND_LEN+TCPMODBUS_LEN+1; 
		} 
		// CMD 
		memory[head].space[offset] = PARA_FUN_ERR; 
		// SubCMD 
		memory[head].space[offset+1] = READ_PARA_ANSWER; 
		// ErrType 
		memory[head].space[offset+2] = ERRtype; 
		if(extend_trans_flag) 
			send_to_serve1(head); 
		else 
			send_data(head,affair_head_info); 
	} 
} 
 
/****************************************************************************** 
* reply a right read request 
* Request :: TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) + Address(2) + Num(1) 
******************************************************************************/ 
void reply_read_OK( uchar pre_head ) 
{ 
	uint	address, Len; 
	uchar	head, num; 
	MEMB	xdata *pd; 
	uchar	mem_offset; 
 
	pd = &(memory[pre_head]); 
	if(!extend_trans_flag) 
	{ 
		if( pd->space[0] == UDP_PROTOCOL ) 
			mem_offset = UDP_DATA_STR; 
		else 
			mem_offset = TCP_DATA_STR; 
	 
		/* Address of request */ 
		address = MAKE_WORD( pd->space[ mem_offset + TCPMODBUS_LEN + 1 + 1 + 1 ], pd->space[ mem_offset + TCPMODBUS_LEN + 1 + 1 + 1 + 1 ] ); 
		/* Num of request */ 
		num = pd->space[ mem_offset + TCPMODBUS_LEN + 1 + 1 + 1 + 2 ]; 
	 
		// Reponse: TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) + DeviceType(1) + dataNum(1) + DataArea 
		Len = 6 + 1 + 1 + 1 + 1 + 1 + num; 
	} 
	else 
	{ 
		/* Address of request */ 
		address = MAKE_WORD( pd->space[TCPMODBUS_LEN +TRANS_COMMAND_LEN+ 1 + 1 + 1 ], pd->space[TCPMODBUS_LEN + TRANS_COMMAND_LEN+1 + 1 + 1 + 1 ] ); 
		/* Num of request */ 
		num = pd->space[TCPMODBUS_LEN + TRANS_COMMAND_LEN + 1 + 1 + 1 + 2 ]; 
	 
		// Reponse: TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) + DeviceType(1) + dataNum(1) + DataArea 
		Len = 6 + 1 + 1 + 1 + 1 + 1 + num + TRANS_COMMAND_LEN;	 
	} 
	head = apply_memb( Len ); 
	if( head != MEMORY_EER ) 
	{ 
		// Prepare include deviceNO(1) 
		PrepareReplyTcpModbusHead( &( memory[head] ) , Len-TCPMODBUS_LEN ); 
		mem_offset = TCPMODBUS_LEN + 1; 
		if(extend_trans_flag) 
		{ 
			PrepareReplyTransHead( head,( Len - TCPMODBUS_LEN ),&( memory[pre_head].space[0])); 
			mem_offset = TRANS_COMMAND_LEN+TCPMODBUS_LEN+1; 
		} 
		// CMD 
		memory[head].space[mem_offset] = PARAMETER_FUN; 
		// SubCMD 
		memory[head].space[mem_offset+1] = READ_PARA_ANSWER; 
		// DeviceType 
		memory[head].space[mem_offset+2] = ( CurWorkState & MASTER_NOT_SLAVE ) ? T_BOX_MASTER : T_BOX_SLAVE; 
		// DataNum 
		memory[head].space[mem_offset+3] = num; 
		// Data 
		pd = &(memory[head]); 
		mem_offset += 4; 
		while( pd ) 
		{ 
			ReadBytesFromFlash( address, (pd->size - mem_offset), &(pd->space[mem_offset]) ); 
			address += (pd->size - mem_offset); 
			pd=pd->link; 
			mem_offset = 0; 
		} 
		if(extend_trans_flag) 
			send_to_serve1(head); 
		else 
			send_data(head,affair_head_info); 
	} 
} 
 
/****************************************************************************** 
* reply a error write request 
*******************************************************************************/ 
void reply_write_ERR( uchar xdata *pd ) 
{ 
	uchar	head; 
	uint	Len; 
 
	if(!extend_trans_flag) 
		// Reponse: TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) + Errtype(1) 
		Len = TCPMODBUS_LEN + 1 + 1 + 1 + 1; 
	else 
		Len = TCPMODBUS_LEN + 1 + 1 + 1 + 1 + TRANS_COMMAND_LEN; 
	head = apply_memb( Len ); 
	if(head != MEMORY_EER) 
	{ 
		uchar offset; 
		// Prepare include deviceNO(1) 
		PrepareReplyTcpModbusHead( &( memory[head] ) , ( Len - TCPMODBUS_LEN ) ); 
		offset = TCPMODBUS_LEN + 1; 
		if(extend_trans_flag) 
		{ 
			PrepareReplyTransHead( head,( Len - TCPMODBUS_LEN ),pd); 
			offset = TRANS_COMMAND_LEN+TCPMODBUS_LEN+1; 
		} 
		// CMD 
		memory[head].space[offset] = PARA_FUN_ERR; 
		// subCMD 
		memory[head].space[offset+1] = WRITE_PARA_ANSWER; 
		// ERRtype 
		memory[head].space[offset+2] = ERRtype; 
		if(extend_trans_flag) 
			send_to_serve1(head); 
		else 
			send_data(head,affair_head_info); 
	} 
} 
 
/********************************************************************************* 
* reply a right write request 
* Request :: TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) + Address(2) + Num(1) + DeviceType(1) + DataArea; 
***********************************************************************************/ 
void reply_write_OK( uchar pre_head ) 
{ 
	uchar	head, num, mem_offset,Len; 
	uint	address; 
	MEMB	xdata *pd; 
	pd = &(memory[pre_head]); 
	if(!extend_trans_flag) 
	{ 
		if( pd->space[0] == UDP_PROTOCOL ) 
			mem_offset = UDP_DATA_STR; 
		else 
			mem_offset = TCP_DATA_STR; 
		/* Address of request */ 
		address = MAKE_WORD( pd->space[ mem_offset + TCPMODBUS_LEN + 1 + 1 + 1 ], pd->space[ mem_offset + TCPMODBUS_LEN + 1 + 1 + 1 + 1 ] ); 
		/* Num of request */ 
		num = pd->space[ mem_offset + TCPMODBUS_LEN + 1 + 1 + 1 + 2 ]; 
		/* Data Area Adrress */ 
		mem_offset += ( TCPMODBUS_LEN + 1 + 1 +1 + 2 + 1 + 1 ); 
		// Reponse: TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) 
		Len = TCPMODBUS_LEN + 1 + 1 + 1; 
	} 
	else 
	{ 
		/* Address of request */ 
		address = MAKE_WORD( pd->space[TCPMODBUS_LEN +TRANS_COMMAND_LEN+ 1 + 1 + 1 ], pd->space[TCPMODBUS_LEN +TRANS_COMMAND_LEN+ 1 + 1 + 1 + 1 ] ); 
		/* Num of request */ 
		num = pd->space[TCPMODBUS_LEN +TRANS_COMMAND_LEN+ 1 + 1 + 1 + 2 ]; 
		/* Data Area Adrress */ 
		mem_offset = ( TCPMODBUS_LEN +TRANS_COMMAND_LEN+ 1 + 1 +1 + 2 + 1 + 1 ); 
		// Reponse: TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) 
		Len = TCPMODBUS_LEN + 1 + 1 + 1 + TRANS_COMMAND_LEN; 
	} 
	/* Write Data to FLASH */ 
	while( pd ) 
	{ 
		WriteMulByteSToFlash( address, pd->size - mem_offset, &(pd->space[mem_offset]) ); 
		address += ( pd->size-mem_offset ); 
		mem_offset = 0; 
		pd = pd->link; 
	} 
 
	// Reponse: TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1) 
 
	head = apply_memb( Len ); 
	if(head != MEMORY_EER) 
	{ 
		// Prepare include deviceNO(1) 
		PrepareReplyTcpModbusHead( &( memory[head] ) , 3); 
		mem_offset = TCPMODBUS_LEN + 1; 
		if(extend_trans_flag) 
		{ 
			PrepareReplyTransHead( head,( 3+TRANS_COMMAND_LEN ),&( memory[pre_head].space[0])); 
			mem_offset = TRANS_COMMAND_LEN+TCPMODBUS_LEN+1; 
		} 
		// CMD 
		memory[head].space[mem_offset] = PARAMETER_FUN; 
		// SubCMD 
		memory[head].space[mem_offset+1] = WRITE_PARA_ANSWER; 
		if(extend_trans_flag) 
			send_to_serve1(head); 
		else 
			send_data(head,affair_head_info); 
	} 
} 
 
/*************************************************************************** 
inspect error for read and write function 
****************************************************************************/ 
bit ERR_chk( uchar xdata *buff ) 
{ 
	uint address; 
	uint num; 
 
	if(extend_trans_flag) 
	{	 
		address = MAKE_WORD( *(buff+TCPMODBUS_LEN+TRANS_COMMAND_LEN+3), *(buff+TCPMODBUS_LEN+TRANS_COMMAND_LEN+4) ); 
		num = *(buff+TCPMODBUS_LEN+TRANS_COMMAND_LEN+5); 
	} 
	else 
	{ 
		address = MAKE_WORD( *(buff+TCPMODBUS_LEN+3), *(buff+TCPMODBUS_LEN+4) ); 
		num = *(buff+TCPMODBUS_LEN+5); 
	} 
	if(address < START_ADDRESS || address > END_ADDRESS || (address+num)>END_ADDRESS) 
	{ 
		ERRtype = ERR_DATA_ADDRESS; 
		return(ERR); 
	} 
	return(OK); 
} 
 
/**************************************************************************************** 
* reply erasure request 
*****************************************************************************************/ 
void reply_erasure( uchar xdata *pd ) 
{ 
	uchar	head; 
	uint	Len,address; 
 
	if(!extend_trans_flag) 
	{ 
		address = MAKE_WORD(*(pd+9),*(pd+10)); 
		EraseFlash( address ); 
		// TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1); 
		Len = TCPMODBUS_LEN + 1 + 1 + 1; 
	} 
	else 
	{ 
		address = MAKE_WORD(*(pd+9+TRANS_COMMAND_LEN),*(pd+10+TRANS_COMMAND_LEN));	 
		EraseFlash( address ); 
		// TCPMODBUS_LEN(6) + deviceNO(1) + CMD(1) + SubCMD(1); 
		Len = TCPMODBUS_LEN + 1 + 1 + 1 + TRANS_COMMAND_LEN; 
	} 
	head = apply_memb( Len ); 
	if(head != MEMORY_EER) 
	{ 
		uchar mem_offset; 
		PrepareReplyTcpModbusHead( &( memory[head] ) , Len - TCPMODBUS_LEN); 
		mem_offset = TCPMODBUS_LEN + 1; 
		if(extend_trans_flag) 
		{ 
			PrepareReplyTransHead( head,( Len - TCPMODBUS_LEN ),pd); 
			mem_offset = TRANS_COMMAND_LEN+TCPMODBUS_LEN+1; 
		} 
		// CMD 
		memory[head].space[mem_offset] = PARAMETER_FUN; 
		// SubCMD 
		memory[head].space[mem_offset+1] = ERASURE_ANSWER; 
		if(extend_trans_flag) 
			send_to_serve1(head); 
		else 
			send_data(head,affair_head_info); 
	} 
} 
 
/****************************************************************************************** 
function: affirm para 
******************************************************************************************/ 
void affirm_para( uchar xdata *pd ) 
{ 
	uchar head; 
	uchar Len; 
	if( CurWorkState & SETPARA_NOT_WORK ) 
		Len = 1; 
	else 
		Len = 0; 
	if( !extend_trans_flag) 
		Len = Len + TCPMODBUS_LEN + 3; 
	else 
	 	Len = Len + TCPMODBUS_LEN + TRANS_COMMAND_LEN + 3; 
#ifdef   TESTDEBUG	 
		Len += 14; 
#endif 
	head = apply_memb( Len ); 
	if(head != MEMORY_EER) 
	{ 
		uchar mem_offset; 
		PrepareReplyTcpModbusHead( &( memory[head] ) , Len - TCPMODBUS_LEN); 
		mem_offset = TCPMODBUS_LEN + 1; 
		if(extend_trans_flag) 
		{ 
			PrepareReplyTransHead( head,(Len - TCPMODBUS_LEN),pd); 
			mem_offset = TRANS_COMMAND_LEN+TCPMODBUS_LEN+1; 
		} 
		// CMD 
		memory[head].space[mem_offset] = PARAMETER_FUN; 
		// SubCMD 
		memory[head].space[mem_offset + 1] = PARA_AFFIRM_ANSWER; 
		// if TBOX is aet para state,reply error 
		if( CurWorkState & SETPARA_NOT_WORK ) 
			memory[head].space[mem_offset + 2] = 0x01; 
#ifdef   TESTDEBUG 
		memory[head].space[mem_offset + 2] = test[0]; 
		memory[head].space[mem_offset + 3] = test[1]; 
		memory[head].space[mem_offset + 4] = test[2]; 
		memory[head].space[mem_offset + 5] = test[3]; 
		memory[head].space[mem_offset + 6] = test[4]; 
		memory[head].space[mem_offset + 7] = test[5]; 
		memory[head].space[mem_offset + 8] = test[6]; 
		memory[head].space[mem_offset + 9] = test[7]; 
		memory[head].space[mem_offset + 10] = test[8]; 
		memory[head].space[mem_offset + 11] = test[9]; 
		memory[head].space[mem_offset + 12] = test[10]; 
		memory[head].space[mem_offset + 13] = test[11]; 
		memory[head].space[mem_offset + 14] = test[12]; 
		memory[head].space[mem_offset + 15] = test[13]; 
#endif 
		if(extend_trans_flag) 
			send_to_serve1(head); 
		else 
			send_data(head,affair_head_info); 
 
		//waite data finish sending  
		mem_offset = 250; 
		while(mem_offset > 0) 
		{ 
			mem_offset--; 
		} 
#ifndef   TESTDEBUG 
		RSTSRC |=0x10; 
#endif 
	} 
} 
 
/******************************************************************************************** 
* function: GetUserNameLen 
********************************************************************************************/ 
/*uchar GetUserNameLen( void ) 
{ 
	uchar 	len = 0; 
	uint	iSetorAdd; 
 
	iSetorAdd = USE_NAME_ADDRESS; 
	while( len <= USER_NAME_MAX_LEN ) 
	{ 
		len++; 
		if( ReadByteFromFlash( iSetorAdd ) == '\0' ) 
		{ 
			return( len ); 
		} 
		iSetorAdd++; 
	} 
}*/ 
 
/******************************************************************************************** 
* function: GetUserPassWordLen 
********************************************************************************************/ 
/*uchar GetUserPassWordLen( void ) 
{ 
	uchar 	len = 0; 
	uint	iSetorAdd; 
 
	iSetorAdd = USE_PASSWORD_ADDRESS; 
	while( len <= USER_PASSWORD_MAX_LEN ) 
	{ 
		len++; 
		if( ReadByteFromFlash( iSetorAdd ) == '\0' ) 
		{ 
			return( len ); 
		} 
		iSetorAdd++; 
	} 
}*/ 
 
/******************************************************************************************** 
* function: Get WordLen  GetWordLen( USE_NAME_ADDRESS ) 
********************************************************************************************/ 
uchar GetWordLen( uint	iSetorAdd ) 
{ 
	uchar 	len = 0; 
	uchar 	max_len; 
	if(iSetorAdd == USE_PASSWORD_ADDRESS) 
		max_len = USER_PASSWORD_MAX_LEN; 
	else 
		max_len = USER_NAME_MAX_LEN; 
	len = max_len; 
	while( len != 0) 
	{ 
		len--; 
		if( ReadByteFromFlash( iSetorAdd ) == '\0' ) 
		{ 
			return( ( max_len - len ) ); 
		} 
		iSetorAdd++; 
	} 
	return(0); 
}