📄 mb_tcp_s.c
字号:
quantity,
&byte_count,
&mb_response_buf[9]
);
}
else
{
//execute defined modbus device read discrete inputs operation
result = mb_read_discrete_inputs(start_address,
quantity,
&byte_count,
&mb_response_buf[9]
);
}
if(MB_NO_ERROR == result)
{
//success
mb_response_buf[8]=byte_count;
response_length += byte_count + 1;
}
break;
//************************************************************************
//Function code 0x05: Write coil
//************************************************************************
case MB_FORCE_SINGLE_COIL :
start_address = ((unsigned int)mb_request_buf[8] << 8)+(unsigned int)mb_request_buf[9];
//execute defined modbus device write coil operation
result = mb_write_coil_func(start_address, mb_request_buf[10]);
if(result == MB_NO_ERROR)
{
mb_response_buf[8] = mb_request_buf[8]; //address hi/lo
mb_response_buf[9] = mb_request_buf[9];
mb_response_buf[10] = mb_request_buf[10]; //output value
mb_response_buf[11] = 0;
response_length += 4;
}
break;
//************************************************************************
//Function code 0x0F: Write multiple coils
//************************************************************************
case MB_FORCE_MULTIPLE_COIL:
start_address = ((unsigned int)mb_request_buf[8] << 8)+(unsigned int)mb_request_buf[9];
quantity = ((unsigned int)mb_request_buf[10] << 8)+(unsigned int)mb_request_buf[11];
result = mb_write_multiple_coils(start_address,quantity,mb_request_buf[12],&mb_request_buf[13]);
if(result==MB_NO_ERROR)
{
mb_response_buf[8] = mb_request_buf[8]; //address hi/lo
mb_response_buf[9] = mb_request_buf[9];
mb_response_buf[10] = mb_request_buf[10]; //quantity
mb_response_buf[11] = mb_request_buf[11];
response_length += 4;
}
break;
//************************************************************************
//Function code 0x03,0x04: Read physical, holding registers
//************************************************************************
case MB_RD_HOLDING_REG :
case MB_RD_INPUT_REG :
start_address = ((unsigned int)mb_request_buf[8] << 8)+(unsigned int)mb_request_buf[9];
quantity = ((unsigned int)mb_request_buf[10] << 8)+(unsigned int)mb_request_buf[11];
if(function_code==MB_RD_HOLDING_REG)
{
result = mb_read_holding_registers(start_address,quantity,(unsigned int *)&mb_response_buf[9],&byte_count);
}
else
{
result = mb_read_input_registers(start_address,quantity,(unsigned int *)&mb_response_buf[9],&byte_count);
}
if(result==MB_NO_ERROR)
{
mb_response_buf[8] = byte_count;
response_length += byte_count + 1; //1 byte bytecount + values
}
break;
//************************************************************************
//Function code 0x06: Write single register
//************************************************************************
case MB_WR_SINGLE_REG :
start_address = ((unsigned int)mb_request_buf[8] << 8)+(unsigned int)mb_request_buf[9];
output_value = ((unsigned int)mb_request_buf[11] << 8)+(unsigned int)mb_request_buf[10];
result = mb_write_single_register(start_address, output_value);
if(result==MB_NO_ERROR)
{
mb_response_buf[8] = mb_request_buf[8]; //address hi/lo
mb_response_buf[9] = mb_request_buf[9];
mb_response_buf[10] = mb_request_buf[10]; //value
mb_response_buf[11] = mb_request_buf[11];
response_length += 4;
}
break;
//************************************************************************
//Function code 0x10: Write multiple contigous registers
//************************************************************************
case MB_WR_MULTIPLE_REG :
start_address = ((unsigned int)mb_request_buf[8] << 8)+(unsigned int)mb_request_buf[9];
quantity = ((unsigned int)mb_request_buf[10] << 8)+(unsigned int)mb_request_buf[11];
result = mb_write_multiple_registers(start_address,quantity,(unsigned int *)&mb_request_buf[13]);
if(result==MB_NO_ERROR)
{
mb_response_buf[8] = mb_request_buf[8]; //address hi/lo
mb_response_buf[9] = mb_request_buf[9];
mb_response_buf[10] = mb_request_buf[10]; //quantity
mb_response_buf[11] = mb_request_buf[11];
response_length += 4;
}
break;
case MB_RD_WR_HOLDING_REG:
//Not implemented yet
break;
//************************************************************************
//Function code 0x2B: Read device identification
//************************************************************************
case MB_RD_DEV_IDENT :
result = mb_read_device_ident(mb_request_buf[8], //MEI
mb_request_buf[9], //read device id code
mb_request_buf[10], //object id
&mb_response_buf[12], //object next
&mb_response_buf[13], //number of objects
&mb_response_buf[11], //more follows flag
&mb_response_buf[14], //start of object list buffer
&read_dev_id_length
);
mb_response_buf[8] = 0x0E; //MEI
if(result==MB_NO_ERROR)
{
mb_response_buf[10] = 0x01; //Set conformity level, here always 1
mb_response_buf[9] = mb_request_buf[9]; //read device code id
response_length += read_dev_id_length + 6; //list + 6 byte response header
}
else
{
mb_response_buf[7] |= 0x80; //or function code
mb_response_buf[9]=(unsigned char)result; //exception code
response_length ++;
}
break;
//************************************************************************
// Unsupported function codes
//************************************************************************
default :result = MB_ILLEGAL; //illegal/unsupported function code
break;
}//switch(function_code)
if(result!=MB_NO_ERROR)
{
if(function_code != MB_RD_DEV_IDENT)
{
mb_response_buf[7] |= 0x80; //or function code
//insert exception code (return value of modbus device function)
mb_response_buf[8] = (unsigned char)result;
}
response_length++;
}
//set length field at MBAB header
mb_response_buf[4]=(unsigned char)((response_length-6)>>8); //Hi
mb_response_buf[5]=(unsigned char)((response_length-6)); //Lo
// - 6 because the first 3 fields of the MBAP are not counted
#ifdef MB_TCP_DEBUG
printf("\r\nmb_tcp_process: Result %d Response length %d\r\n",result,response_length);
printf("\r\nResponse MBAB: ");
for(i=0;i<7;i++)
{
printf(" %02X",mb_response_buf[i]);
}
printf("\r\nResponse PDU: ");
for(i=7;i<response_length;i++)
{
printf(" %02X",mb_response_buf[i]);
}
#endif
//send response
if(API_ERROR == send( sd, (char *)mb_response_buf, response_length, 0, &error))
{
#ifdef MB_TCP_DEBUG
printf("\r\nmb_tcp_process: Send reply failed %d",error);
#endif
return MB_TCP_ERROR;
}
return MB_NO_ERROR;
}
/******************************************************************************
* main() modbus tcp server loop
******************************************************************************/
int main(void)
{
struct sockaddr_in addr;
struct sockaddr_in claddr;
int sd;
int asd;
int mb_tcp_state; //modbus tcp state variable
int error,retval;
//********************************
//init modbus device
//********************************
if(MB_NO_ERROR!=mb_dev_init())
{
printf("\r\nModbus server device init failed");
return MB_ERROR;
}
//****************************************************************
//Initialize tcp server
//****************************************************************
printf("\r\nModbus TCP server: Listening on port %d\r\n",MB_PORT);
sd = opensocket( SOCK_STREAM, &error );
if(sd == API_ERROR)
{
printf("\r\nModbus TCP server: Socket open failed: %d",error);
goto MB_TCP_SERVER_DONE;
}
addr.sin_family = PF_INET;
addr.sin_port = htons(MB_PORT);
addr.sin_addr.s_addr = 0L;
if(API_ERROR == bind( sd, (const struct sockaddr *)&addr, &error ))
{
printf("\r\nModbus TCP server: Socket bind failed: %d",error);
goto MB_TCP_SERVER_DONE;
}
while(1)
{
mb_tcp_state = MB_TCP_IDLE;
/**********************************************************************/
//Wait for connection
/**********************************************************************/
if(API_ERROR==listen( sd, 1, &error))
{
printf("\r\nModbus TCP server: Socket listen failed: %d",error);
goto MB_TCP_SERVER_DONE;
}
claddr.sin_family = PF_INET;
claddr.sin_port = 0;
claddr.sin_addr.s_addr = 0L;
asd = accept( sd, (struct sockaddr *)&claddr, &error );
if(asd == API_ERROR)
{
printf("\r\nModbus TCPserver: Socket accept failed: %d",error);
goto MB_TCP_SERVER_DONE;
}
#ifdef MB_TCP_DEBUG
InetToAscii( (unsigned long *) &claddr.sin_addr.s_addr, ClientIP );
printf("\r\nModbus TCP: Connected with %s , Port %u\r\n",ClientIP, htons(claddr.sin_port));
#endif
//Check authorization
if(MB_ERROR==mb_tcp_authorized(claddr.sin_addr.s_addr))
{
continue;
}
mb_tcp_state = MB_TCP_CONN;
/**********************************************************************/
//Connection established: Wait and serve client modbus requests
/**********************************************************************/
while(mb_tcp_state == MB_TCP_CONN)
{
/*******************************************************************/
//Wait for incoming modbus requests from client
/*******************************************************************/
retval = mb_tcp_recv_request(asd, mb_tcp_request_buf);
if(retval== MB_ERROR)
{
//Receiving request timeout, try to receive a new request
#ifdef MB_TCP_DEBUG
printf("\r\n\r\nModbus TCP server: mb_tcp_recv timed out");
#endif
continue;
}
else
{
if(retval==MB_TCP_ERROR)
{
//Tcp socket error has occured, close current socket connection and wait for new one
#ifdef MB_TCP_DEBUG
printf("\r\n\r\nModbus TCP server: mb_tcp_recv socket error occured");
#endif
mb_tcp_state = MB_TCP_IDLE;
break;
}
}
/*******************************************************************/
//Process the incoming modbus request, stored a recvbuf
/*******************************************************************/
if(MB_TCP_ERROR==mb_tcp_process_request(asd, mb_tcp_request_buf, mb_tcp_response_buf))
{
//Tcp socket send error has occured, close current socket connection and wait for new one
#ifdef MB_TCP_DEBUG
printf("\r\n\r\nModbus TCP server: mb_tcp_process socket send error occured");
#endif
mb_tcp_state = MB_TCP_IDLE;
break;
}
}//while(mb_tcp_state==MB_TCP_CONN)
//Close current connection
closesocket( asd, &error );
#ifdef MB_TCP_DEBUG
printf("\r\nModbus TCP server: Connection closed error %d",error);
#endif
}//while(1)
MB_TCP_SERVER_DONE:
mb_dev_deinit();
closesocket( sd, &error );
return 0;
}
//------------------------------------------------------------------------------
// End of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -