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


/****************************************************************************** 
 * Project     : t_box 
 * Module Name : applyPLAY.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	"o:/lwip/udp.h" 
#include	"o:/lwip/tcp.h" 
 
#include  
#define  LISTSIZE			32 
#define	 DYNAMIC_IP_COUNT 	19 
#define TRANSACTION_LIST_SIZE 3 
 
bit	 data  com_flag;    							/*commu data apply no success*/	  
uchar data Pre_station_num = 0; 
uint data Com_Transaction_num = 0; 
static uint	idata	Transaction_list[TRANSACTION_LIST_SIZE];	// store Transaction identifier( identifier must not be a '0' )  
static uchar GetTcpModbusData( uchar offset ); 
/**************************************************************** 
* get data taht use tcp receive 
****************************************************************/ 
uchar get_UDP_data( void ) 
{ 
	uchar	head;	 
	uchar xdata *pd; 
	bit flag = NO; 
	pd = (uchar xdata *)(pCashData->payload); 
	if(*(pd+TCPMODBUS_LEN+1) == LAND_FUNCTION && *(pd+TCPMODBUS_LEN+2) == SERVERTANSMESSAGE ) 
	{ 
		flag = YES; 
		head = GetTcpModbusData( 0 ); 
	} 
	else 
		head = GetTcpModbusData( UDP_DATA_STR ); 
	if( head != MEMORY_EER ) 
	{ 
		UDP_INFO xdata *pUdp_Info; 
		if(flag) 
		{ 
			memory[head].tag |= SERVE_TRANS_MESSAGE;				/* serve transfer message */  
		} 
		else 
		{ 
			pUdp_Info = (UDP_INFO xdata*)(memory[head].space); 
			pUdp_Info->uchProtocol = UDP_PROTOCOL; 
			pUdp_Info->ulIP = UDP_Sender_Address.sender_IP; 
			pUdp_Info->uiPort = UDP_Sender_Address.sender_PORT; 
			pUdp_Info->selfPort = UDP_Sender_Address.Self_PORT;  /*new change*/ 
		} 
	} 
	return(head); 
} 
 
/***************************************************************************************** 
* when TBOX type is slave, called 
* Return: static table slave station's count  
*******************************************************************************************/ 
uchar Calcuate_SlaveStationNum( void ) 
{ 
	uchar m ,i; 
	 
	i = 0; 
	for( m = 1; mpayload); 
	if(((pTcpModbusHead->DataLen + TCPMODBUS_LEN) > pCashData->tot_len) || pTcpModbusHead->DataLen < 3 ) 
	{ 
		pbuf_free(pCashData);  
		pCashData = NULL; 
		return(MEMORY_EER); 
	} 
	Len = offset + TCPMODBUS_LEN + pTcpModbusHead->DataLen; 
	head = apply_memb( Len ); 
	if( head != MEMORY_EER ) 
	{ 
		pd = &( memory[head] ); 
		buff = (uchar xdata *)(pCashData->payload); 
		while( pd ) 
		{ 
			while( offset < pd->size ) 
			{ 
				pd->space[offset] = *buff; 
				buff++; 
				offset++; 
			} 
			pd=pd->link; 
			offset = 0; 
		} 
		pbuf_header( pCashData, (-(pTcpModbusHead->DataLen + TCPMODBUS_LEN)) ); 
		 
		if( (pCashData->tot_len == 0) || (pCashData->tot_len < TCPMODBUS_LEN)) 
		{ 
			pbuf_free(pCashData);		/*no function*/ 
			pCashData = NULL; 
		} 
 
		if( pTcpModbusHead->Protocol_Identifier == TCPMODBUS_PROTOCOL ) 
		{	 
		} 
		else 
		{/*other protocol process*/} 
		return(head); 
	} 
} 
 
/******************************************************************* 
* TBOX use UART communicate to equipment 
**********************************************************************/ 
void UART_transmitted( uchar head ) 
{ 
	uchar Len; 
	uchar offset; 
	MEMB xdata *pd; 
 
	pd = &(memory[head]); 
	if( CurWorkState & MASTER_NOT_SLAVE ) 
	{ 
		if( ( (memory[head].tag) & 0x40 ) != SERVE_TRANS_MESSAGE ) 
		{ 
			if( pd->space[0] == UDP_PROTOCOL ) 
				offset = UDP_DATA_STR; 
			else 
			{ 
				offset = TCP_DATA_STR; 
			} 
			// TCPMODBUS's front two byTe is 'sequence number' 
			if(query_Transaction( MAKE_WORD( pd->space[offset],pd->space[offset+1] ) ) == OK) 
			{ 
				del_Transaction( MAKE_WORD( pd->space[offset],pd->space[offset+1] ) ); 
				Com_Transaction_num = 0; 
				offset += TCPMODBUS_LEN; 
				// Copy data to ComSend Buffer 
				Len  = 0; 
				while( pd ) 
				{ 
					while( offset < pd->size ) 
					{ 
						CommuBuffer[Len] = pd->space[offset]; 
						offset++; 
						Len++; 
					} 
					pd = pd->link; 
					offset = 0; 
				} 
				RSTsend(Len, CommuBuffer); 
			} 
		} 
		free_memb( &(memory[head]) ); 
	} 
	else  
	{ 
		enter_affair_queue( head );		 
	} 
} 
 
/************************************************************************* 
* query equipment number is or not in equipment_list 
* return Value: 0: not find; 1: in static stable; 2: in dynamic stable 
*************************************************************************/ 
uchar query_equipment_list(uchar equipment_number) 
{ 
	/*uchar i,tmp,number; 
	uchar chTmp; 
 
	number = (equipment_number - 1) / BYTE_WIDTH;		 
	i = (equipment_number - 1) % BYTE_WIDTH; 
 
		chTmp = ReadByteFromFlash( STATIC_STATION_ADDRESS+number );		 
		tmp = chTmp; 
		tmp = tmp >> i; 
		tmp = (tmp & 0x01); 
		if( tmp != 0 ) 
		{ 
			return( STATIC_LIST ); 
		} 
		return ( ERR );*/ 
	if(ReadByteFromFlash( STATIC_STATION_ADDRESS + equipment_number ) != 0 ) 
		return(OK); 
	else 
		return ( ERR );	 
/*	} 
	return ( DYNAMIC_LIST );*/ 
} 
 
/********************************************************************************* 
* get a station's ip, add this ip to station_IP_LIST  ip_station_list 
*********************************************************************************/ 
void add_station_IP( uchar station,ulong IP_value ) 
{ 
	uint  tmp; 
	uchar uOffset1; 
	MEMB xdata *pd1; 
 
	if(ip_station_list->space[0] == DYNAMIC_IP_COUNT) 
	{ 
		uchar i; 
		uchar uOffset2; 
		MEMB xdata *pd2; 
 
		uOffset1 = 1; 
		uOffset2 = 1+1*5; 
		pd1 = ip_station_list; 
		pd2 = ip_station_list; 
		// move 'DYNAMIC_IP_COUNT-1' item ahead line 
		for( i=0; i<((DYNAMIC_IP_COUNT-1)*5); i++ ) 
		{ 
			pd1->space[uOffset1] = pd2->space[uOffset2]; 
			uOffset1++; 
			uOffset2++; 
			if( uOffset1 == SPACE_SIZE ) 
			{ 
				uOffset1 = 0; 
				pd1 = pd1->link; 
			} 
			if( uOffset2 == SPACE_SIZE ) 
			{ 
				uOffset2 = 0; 
				pd2 = pd2->link; 
			} 
		} 
		ip_station_list->space[0]--; 
	} 
 
	/*find address which add station and ip*/ 
	uOffset1 = ip_station_list->space[0] * 5 + 1; 
	pd1 = ip_station_list; 
	while( uOffset1 >= SPACE_SIZE ) 
	{ 
		pd1 = pd1->link; 
		uOffset1 -= SPACE_SIZE; 
	} 
 
	pd1->space[ uOffset1++ ] = station; 
	if( uOffset1 == SPACE_SIZE ) 
	{ 
		uOffset1 = 0; 
		pd1 = pd1->link; 
	} 
	tmp = HIGH_WORD(IP_value); 
	pd1->space[ uOffset1++ ] = HIGH_BYTE( tmp ); 
	if( uOffset1 == SPACE_SIZE ) 
	{ 
		uOffset1 = 0; 
		pd1 = pd1->link; 
	} 
	pd1->space[ uOffset1++ ] = LOW_BYTE( tmp ); 
	if( uOffset1 == SPACE_SIZE ) 
	{ 
		uOffset1 = 0; 
		pd1 = pd1->link; 
	} 
	tmp = LOW_WORD( IP_value ); 
	pd1->space[ uOffset1++ ] = HIGH_BYTE( tmp ); 
	if( uOffset1 == SPACE_SIZE ) 
	{ 
		uOffset1 = 0; 
		pd1 = pd1->link; 
	} 
	pd1->space[ uOffset1++ ] = LOW_BYTE( tmp ); 
	if( uOffset1 == SPACE_SIZE ) 
	{ 
		uOffset1 = 0; 
		pd1 = pd1->link; 
	} 
	ip_station_list->space[0]++; 
} 
 
/**************************************************************************** 
delet a ip address of station in dynamic station_IP_LIST 
****************************************************************************/ 
void del_station_IP( uchar station ) 
{ 
	uchar i,offset1,offset2; 
	MEMB xdata *pd1,*pd2; 
 
	pd1 = ip_station_list; 
	offset1 = 1; 
	for( i = 0; ispace[0]; i++ ) 
	{ 
		if( station == pd1->space[offset1] ) 
			break; 
		offset1 += 5; 
		if( offset1 >= SPACE_SIZE ) 
		{ 
			pd1 = pd1->link; 
			offset1 -= SPACE_SIZE; 
		} 
	} 
 
	if( i == ip_station_list->space[0] ) 
		return; 
 
	/* move data */ 
	offset2 = offset1+5; 
	if( offset2 >= SPACE_SIZE ) 
	{ 
		offset2 -= SPACE_SIZE; 
		pd2 = pd1->link; 
	} 
	else 
		pd2 = pd1; 
	for( i=(i+1)*5; i<(ip_station_list->space[0]*5); i++ ) 
	{ 
		pd1->space[offset1] = pd2->space[offset2]; 
		offset1++; 
		offset2++; 
		if( offset1 == SPACE_SIZE ) 
		{ 
			offset1 = 0; 
			pd1 = pd1->link; 
		} 
		if( offset2 == SPACE_SIZE ) 
		{ 
			offset2 = 0; 
			pd2 = pd2->link; 
		} 
	} 
	ip_station_list->space[0]--; 
} 
 
/******************************************************************************* 
* query this station's IP is or not in station_IP list 
* station_IP_LIST{station_NUM,ip,port}totle 7 byte 
********************************************************************************/ 
uchar station_IP( uchar station ) 
{ 
	uchar i,offset; 
	uchar number,count; 
	MEMB xdata *pd; 
	/*count = station_IP_LIST[0]; 
	for( i = 0; ispace[0]; 
	pd = ip_station_list; 
	offset = 1; 
	for( i = 0; ispace[offset] ) 
			return( DYNAMIC_LIST ); 
		offset += 5; 
		if( offset >= SPACE_SIZE ) 
		{ 
			offset -= SPACE_SIZE; 
			pd = pd->link; 
		} 
	} 
 
	count = ReadByteFromFlash( STATIC_IP_STATION_ADDRESS );			/*get station count in flash*/ 
	for( i = 0; i>i; 
	tmp &= 0x01; 
	if( tmp == 0x00 ) 
	{ 
		return(ERR); 
	} 
	return ( OK );*/ 
	if(ReadByteFromFlash( STATIC_SHIELD_ADDRESS + station_num ) != 0 ) 
		return(OK); 
	else 
		return ( ERR );	 
} 
 
/************************************************************************* 
if preceding station is not reply,delet this station from dynamic 
*************************************************************************/ 
void check_station_reply( void ) 
{ 
	/* check preceding station is or not reply*/ 
	if( Com_Transaction_num != 0 ) 
	{ 
#ifdef   TESTDEBUG	 
test[13]++; 
#endif 
		if(query_Transaction(Com_Transaction_num) == OK) 
		{			 
			del_Transaction( Com_Transaction_num ); 
			Com_Transaction_num = 0;/*preceding station not reply*/ 
			if( Pre_station_num != BROADCAST ) 
			{ 
				/*now station is not preceding station*/ 
				if( station_IP(Pre_station_num) == DYNAMIC_LIST ) 
					del_station_IP(Pre_station_num); 
			} 
		} 
	} 
} 
 
/************************************************************************* 
make request message(master) 
**************************************************************************/ 
void make_request_message(uchar len, uchar xdata *pd) 
{ 
	uchar head; 
	ulong ip; 
 
	head = apply_memb(len+TCPMODBUS_LEN);		 
	if(head != MEMORY_EER) 
	{ 
		PrepareHostSenderTcpModbusHead( &(memory[head]), len ); 
		Com_Transaction_num = MAKE_WORD( memory[head].space[0], memory[head].space[1] ); 
		add_data(len,head,pd,6); 
		if(*pd == 0) 
		{ 
			UDP_send_data( head,0xFFFFFFFF,502,UDP_LOCAL_PORT);		/*broadcast*/ 
		} 
		else 
		{ 
			ip = get_ip( *pd ); 
			if(comm_send_protocol == TCP_PROTOCOL) 
				TCP_send_data(head,ip); 
			else 
				UDP_send_data(head,ip,UDP_LOCAL_PORT,UDP_LOCAL_PORT); 
		} 
		/*remember send dest station*/ 
		Pre_station_num = CommuBuffer[0]; 
	} 
#ifdef   TESTDEBUG 
	else 
		test[12]++; 
#endif 
} 
 
/****************************************************************************** 
* make response message( slave ) 
******************************************************************************/ 
void make_response_message(uchar len, uchar xdata *pd) 
{ 
	uchar head, offset; 
	if(head_info[0] != SERVE_TRANS_MESSAGE) 
	{ 
		if(head_info[0] ==  UDP_PROTOCOL) 
		{ 
			offset = UDP_DATA_STR + TCPMODBUS_LEN; 
		} 
		else 
		{ 
			offset = TCP_DATA_STR + TCPMODBUS_LEN; 
		} 
		if( *pd == head_info[offset] )		/*is or not need reply*/ 
		{ 
			head = apply_memb( len + TCPMODBUS_LEN ); 
			if( head != MEMORY_EER ) 
			{ 
				memory[head].TCP_connect_num = 0x80 | head_info[14]; 
				PrepareCommReplyTcpModbusHead( &(memory[head]),len ); 
				add_data( len, head, pd, 6 ); 
				send_com_data(head, head_info); 
				com_flag  = NO; 
			} 
			else 
			{ 
				com_flag  = YES; 
			}  
		} 
	} 
	else 
	{ 
		if(*pd == head_info[3])	 
		{ 
			head = apply_memb( len + TCPMODBUS_LEN + TRANS_COMMAND_LEN + 1); 
			if( head != MEMORY_EER ) 
			{ 
				uchar i; 
				memory[head].space[0] = head_info[1]; 
				memory[head].space[1] = head_info[2]; 
				memory[head].space[2] = 0; 
				memory[head].space[3] = 0; 
				memory[head].space[4] = HIGH_BYTE(len + TRANS_COMMAND_LEN + 1); 
				memory[head].space[5] = LOW_BYTE(len + TRANS_COMMAND_LEN + 1); 
				memory[head].space[6] = *pd; 
				memory[head].space[7] = LAND_FUNCTION; 
				memory[head].space[8] = ASKSERVERTRANS; 
				for(i=0;i<7;i++) 
				memory[head].space[9+i] = head_info[4+i]; 
				add_data( (len-1), head, (pd+1), (TCPMODBUS_LEN + TRANS_COMMAND_LEN + 1) ); 
				/*send to serve1*/ 
				send_to_serve1(head); 
				com_flag  = NO; 
			} 
			else 
			{ 
				com_flag  = YES; 
			} 
		} 
	} 
} 
 
/************************************************************************* 
* Para: 	pd:		SAVE TCPMODBUS'HEAD Area  
*			Len:	TCPMODBUS DATA AREA LENGTH 
			offset: data address offset 
*************************************************************************/ 
void PrepareCommReplyTcpModbusHead( MEMB xdata *pd, uint Len ) 
{ 
	uchar offset; 
	if(head_info[0] ==  UDP_PROTOCOL) 
		offset = UDP_DATA_STR; 
	else 
		offset = TCP_DATA_STR;	// TCP 
	pd->space[0] = head_info[offset]; 
	pd->space[1] = head_info[offset + 1]; 
	pd->space[2] = head_info[offset + 2]; 
	pd->space[3] = head_info[offset + 3]; 
	pd->space[4] = HIGH_BYTE( Len ); 
	pd->space[5] = LOW_BYTE( Len ); 
} 
 
/****************************************************************************** 
* add COMM data into memory  
******************************************************************************/ 
void add_data( uchar len,uchar head,uchar xdata *pd,uchar offset ) 
{ 
	MEMB xdata *tmp_pd; 
	uchar i; 
 
	i = 0; 
	tmp_pd = &(memory[head]); 
	while(len != 0 ) 
	{ 
		while(offsetspace[offset] = *(pd+i); 
			offset++; 
			i++; 
			len--; 
			if(len == 0) break; 
		} 
		if(len != 0) 
		{ 
			tmp_pd=tmp_pd->link; 
			offset = 0; 
		} 
	} 
} 
 
/************************************************************************* 
* get station's ip in flash or dynamic list 
*************************************************************************/ 
ulong get_ip(uchar station ) 
{ 
	ulong ip; 
	uchar i,offset; 
	MEMB xdata *pd; 
	uchar uCount; 
 
	pd = ip_station_list; 
	offset = 1; 
	for( i=0; ispace[0]; i++ ) 
	{ 
		if( station == pd->space[offset] ) 
		{ 
			ip = 0; 
			for( i=0; i<4; i++ ) 
			{ 
				ip *= 256; 
				offset++; 
				if( offset >= SPACE_SIZE ) 
				{ 
					offset -= SPACE_SIZE; 
					pd = pd->link; 
				} 
				ip += pd->space[offset]; 
			} 
			return( ip ); 
		} 
		offset += 5; 
		if( offset >= SPACE_SIZE ) 
		{ 
			offset -= SPACE_SIZE; 
			pd = pd->link; 
		} 
	} 
 
	/* 'ReadByteFromFlash(STATIC_IP_STATION_ADDRESS)' IS get station count in flash*/ 
	uCount = ReadByteFromFlash(STATIC_IP_STATION_ADDRESS); 
	for( i = 0; i