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; m payload); 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; i space[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; i space[0]; pd = ip_station_list; offset = 1; for( i = 0; i space[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(offset space[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; i space[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