mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 18:47:22 +00:00
Incremental changes for SOL. Support for breaks (R. Sunshine). Much
refactoring and cleanup. More coming soon.
This commit is contained in:
parent
9627ab3253
commit
bf5e378272
@ -67,8 +67,7 @@
|
||||
|
||||
static struct termios _saved_tio;
|
||||
static int _in_raw_mode = 0;
|
||||
|
||||
|
||||
static int bShouldExit = 0;
|
||||
|
||||
extern int verbose;
|
||||
|
||||
@ -719,6 +718,28 @@ void enter_raw_mode(void)
|
||||
}
|
||||
|
||||
|
||||
static void sendBreak(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_v2_payload v2_payload;
|
||||
|
||||
memset(&v2_payload, 0, sizeof(v2_payload));
|
||||
|
||||
v2_payload.payload_length = 0;
|
||||
v2_payload.payload.sol_packet.generate_break = 1;
|
||||
|
||||
intf->send_sol(intf, &v2_payload);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* suspendSelf
|
||||
*
|
||||
* Put ourself in the background
|
||||
*
|
||||
* param bRestoreTty specifies whether we will put our self back
|
||||
* in raw mode when we resume
|
||||
*/
|
||||
static void suspendSelf(int bRestoreTty)
|
||||
{
|
||||
leave_raw_mode();
|
||||
@ -730,21 +751,87 @@ static void suspendSelf(int bRestoreTty)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* printSolEscapeSequences
|
||||
*
|
||||
* Send some useful documentation to the user
|
||||
*/
|
||||
void printSolEscapeSequences()
|
||||
{
|
||||
printf(
|
||||
"~?\r\n\
|
||||
"%c?\r\n\
|
||||
Supported escape sequences:\r\n\
|
||||
~. - terminate connection\r\n\
|
||||
~^Z - suspend ipmitool\r\n\
|
||||
~^X - suspend ipmitool, but don't restore tty on restart\r\n\
|
||||
~? - this message\r\n\
|
||||
~~ - send the escape character by typing it twice\r\n\
|
||||
(Note that escapes are only recognized immediately after newline.)\r\n");
|
||||
%c. - terminate connection\r\n\
|
||||
%c^Z - suspend ipmitool\r\n\
|
||||
%c^X - suspend ipmitool, but don't restore tty on restart\r\n\
|
||||
%cb - send break\r\n\
|
||||
%c? - this message\r\n\
|
||||
%c%c - send the escape character by typing it twice\r\n\
|
||||
(Note that escapes are only recognized immediately after newline.)\r\n",
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER,
|
||||
SOL_ESCAPE_CHARACTER);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* output
|
||||
*
|
||||
* Send the specified data to stdout
|
||||
*/
|
||||
static void output(char * data, int length)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < length; ++i)
|
||||
putc(data[i], stdout);
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* impi_sol_deactivate
|
||||
*/
|
||||
static int ipmi_sol_deactivate(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
unsigned char data[6];
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = IPMI_DEACTIVATE_PAYLOAD;
|
||||
req.msg.data_len = 6;
|
||||
req.msg.data = data;
|
||||
|
||||
bzero(data, sizeof(data));
|
||||
data[0] = IPMI_PAYLOAD_TYPE_SOL; /* payload type */
|
||||
data[1] = 1; /* payload instance. Guess! */
|
||||
|
||||
/* Lots of important data */
|
||||
data[2] = 0;
|
||||
data[3] = 0;
|
||||
data[4] = 0;
|
||||
data[5] = 0;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp || rsp->ccode) {
|
||||
printf("Error:%x Dectivating SOL payload\n",
|
||||
rsp ? rsp->ccode : 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* processSolUserInput
|
||||
*
|
||||
@ -767,11 +854,16 @@ static int processSolUserInput(struct ipmi_intf * intf,
|
||||
char ch;
|
||||
int i;
|
||||
|
||||
memset(&v2_payload, 0, sizeof(v2_payload));
|
||||
|
||||
/*
|
||||
* Our first order of business is to check the input for escape
|
||||
* sequences to act on.
|
||||
*/
|
||||
for (i = 0; i < buffer_length; ++i)
|
||||
{
|
||||
ch = input[i];
|
||||
|
||||
//if (escape_pending && (ch != SOL_ESCAPE_CHARACTER)) {
|
||||
if (escape_pending){
|
||||
escape_pending = 0;
|
||||
|
||||
@ -780,10 +872,9 @@ static int processSolUserInput(struct ipmi_intf * intf,
|
||||
*/
|
||||
switch (ch) {
|
||||
case '.':
|
||||
/* Terminate the connection. */
|
||||
/* Should probably flush our buffer first */
|
||||
return 1;
|
||||
continue;
|
||||
printf("%c. [terminated ipmitool]\r\n", SOL_ESCAPE_CHARACTER);
|
||||
retval = 1;
|
||||
break;
|
||||
case 'Z' - 64:
|
||||
printf("%c^Z [suspend ipmitool]\r\n", SOL_ESCAPE_CHARACTER);
|
||||
suspendSelf(1); /* Restore tty back to raw */
|
||||
@ -794,6 +885,11 @@ static int processSolUserInput(struct ipmi_intf * intf,
|
||||
suspendSelf(0); /* Don't restore to raw mode */
|
||||
continue;
|
||||
|
||||
case 'b':
|
||||
printf("%cb [send break]\r\n", SOL_ESCAPE_CHARACTER);
|
||||
sendBreak(intf);
|
||||
continue;
|
||||
|
||||
case '?':
|
||||
printSolEscapeSequences();
|
||||
continue;
|
||||
@ -823,19 +919,28 @@ static int processSolUserInput(struct ipmi_intf * intf,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If there is anything left to process we dispatch it to the BMC
|
||||
*/
|
||||
if (length)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
|
||||
v2_payload.payload_length = length;
|
||||
rsp = intf->send_sol(intf, &v2_payload);
|
||||
|
||||
//memcpy(v2_payload.payload.sol_packet.data,
|
||||
// input,
|
||||
// v2_payload.payload_length);
|
||||
|
||||
if (intf->send_sol(intf, &v2_payload))
|
||||
/* This will always fail until we wait for our ACKs */
|
||||
if (! rsp)
|
||||
{
|
||||
printf("Error sending SOL data\n");
|
||||
retval = -1;
|
||||
//printf("Error sending SOL data\n");
|
||||
//retval = -1;
|
||||
}
|
||||
|
||||
/* If the sequence number is set we know we have new data */
|
||||
//else if ((rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) &&
|
||||
// (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) &&
|
||||
// (rsp->payload.sol_packet.packet_sequence_number))
|
||||
// output(rsp->data, rsp->data_len);
|
||||
}
|
||||
|
||||
return retval;
|
||||
@ -882,11 +987,12 @@ static int ipmi_sol_red_pill(struct ipmi_intf * intf)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process input from the user
|
||||
*/
|
||||
if (FD_ISSET(0, &read_fds))
|
||||
{
|
||||
/*
|
||||
* Received input from the user
|
||||
*/
|
||||
{
|
||||
bzero(buffer, sizeof(buffer));
|
||||
numRead = read(fileno(stdin),
|
||||
buffer, sizeof(buffer));
|
||||
@ -894,10 +1000,14 @@ static int ipmi_sol_red_pill(struct ipmi_intf * intf)
|
||||
if (numRead > 0)
|
||||
{
|
||||
int rc = processSolUserInput(intf, buffer, numRead);
|
||||
|
||||
if (rc)
|
||||
bShouldExit = 1;
|
||||
if (rc < 1)
|
||||
bBmcClosedSession = 1;
|
||||
{
|
||||
if (rc < 0)
|
||||
bShouldExit = bBmcClosedSession = 1;
|
||||
else
|
||||
bShouldExit = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -905,11 +1015,12 @@ static int ipmi_sol_red_pill(struct ipmi_intf * intf)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process input from the BMC
|
||||
*/
|
||||
else if (FD_ISSET(intf->fd, &read_fds))
|
||||
{
|
||||
/*
|
||||
* Received input from the BMC.
|
||||
*/
|
||||
int i;
|
||||
struct ipmi_rs * rs =intf->recv_sol(intf);
|
||||
if (! rs)
|
||||
@ -917,17 +1028,15 @@ static int ipmi_sol_red_pill(struct ipmi_intf * intf)
|
||||
bShouldExit = bBmcClosedSession = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < rs->data_len; ++i)
|
||||
putc(rs->data[i], stdout);
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
output(rs->data, rs->data_len);
|
||||
}
|
||||
|
||||
|
||||
else
|
||||
/*
|
||||
* ERROR in select
|
||||
*/
|
||||
else
|
||||
{
|
||||
/* ERROR */
|
||||
printf("Error: Select returned with nothing to read\n");
|
||||
bShouldExit = 1;
|
||||
}
|
||||
@ -941,46 +1050,14 @@ static int ipmi_sol_red_pill(struct ipmi_intf * intf)
|
||||
printf("SOL session closed by BMC\n");
|
||||
exit(1);
|
||||
}
|
||||
else
|
||||
ipmi_sol_deactivate(intf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* impi_sol_deactivate
|
||||
*/
|
||||
static int ipmi_sol_deactivate(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_rs * rsp;
|
||||
struct ipmi_rq req;
|
||||
unsigned char data[6];
|
||||
|
||||
req.msg.netfn = IPMI_NETFN_APP;
|
||||
req.msg.cmd = IPMI_DEACTIVATE_PAYLOAD;
|
||||
req.msg.data_len = 6;
|
||||
req.msg.data = data;
|
||||
|
||||
bzero(data, sizeof(data));
|
||||
data[0] = IPMI_PAYLOAD_TYPE_SOL; /* payload type */
|
||||
data[1] = 1; /* payload instance. Guess! */
|
||||
|
||||
/* Lots of important data */
|
||||
data[2] = 0;
|
||||
data[3] = 0;
|
||||
data[4] = 0;
|
||||
data[5] = 0;
|
||||
|
||||
rsp = intf->sendrecv(intf, &req);
|
||||
|
||||
if (!rsp || rsp->ccode) {
|
||||
printf("Error:%x Dectivating SOL payload\n",
|
||||
rsp ? rsp->ccode : 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1065,14 +1142,6 @@ static int ipmi_sol_activate(struct ipmi_intf * intf)
|
||||
#endif
|
||||
|
||||
|
||||
printf("max inbound payload size : %d\n",
|
||||
intf->session->sol_data.max_inbound_payload_size);
|
||||
printf("max outbound payload size : %d\n",
|
||||
intf->session->sol_data.max_outbound_payload_size);
|
||||
printf("SOL port : %d\n",
|
||||
intf->session->sol_data.port);
|
||||
|
||||
|
||||
if (intf->session->sol_data.port != intf->session->port)
|
||||
{
|
||||
printf("Error: BMC requests SOL session on different port\n");
|
||||
@ -1080,6 +1149,10 @@ static int ipmi_sol_activate(struct ipmi_intf * intf)
|
||||
}
|
||||
|
||||
|
||||
printf("[SOL Session operational. Use %c? for help]\r\n",
|
||||
SOL_ESCAPE_CHARACTER);
|
||||
|
||||
|
||||
/*
|
||||
* At this point we are good to go with our SOL session. We
|
||||
* need to listen to
|
||||
@ -1104,6 +1177,8 @@ void print_sol_usage()
|
||||
{
|
||||
printf("SOL Commands: info [<channel number>]\n");
|
||||
printf(" set <parameter> <value> [channel]\n");
|
||||
printf(" activate\n");
|
||||
printf(" deactivate\n");
|
||||
}
|
||||
|
||||
|
||||
@ -1140,6 +1215,7 @@ int ipmi_sol_main(struct ipmi_intf * intf, int argc, char ** argv)
|
||||
retval = ipmi_print_sol_info(intf, channel);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set a parameter value
|
||||
*/
|
||||
|
@ -102,8 +102,12 @@ static void read_session_data_v2x(struct ipmi_rs * rsp, int * offset, struct ipm
|
||||
static void read_ipmi_response(struct ipmi_rs * rsp, int * offset);
|
||||
static void read_sol_packet(struct ipmi_rs * rsp, int * offset);
|
||||
static struct ipmi_rs * ipmi_lanplus_recv_sol(struct ipmi_intf * intf);
|
||||
static int ipmi_lanplus_send_sol(struct ipmi_intf * intf,
|
||||
struct ipmi_v2_payload * payload);
|
||||
static struct ipmi_rs * ipmi_lanplus_send_sol(struct ipmi_intf * intf,
|
||||
struct ipmi_v2_payload * payload);
|
||||
static int check_sol_packet_for_data(struct ipmi_intf * intf,
|
||||
struct ipmi_rs *rsp);
|
||||
static void ack_sol_packet(struct ipmi_intf * intf,
|
||||
struct ipmi_rs * rsp);
|
||||
|
||||
|
||||
struct ipmi_intf ipmi_lanplus_intf = {
|
||||
@ -605,7 +609,10 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
||||
}
|
||||
|
||||
|
||||
else if (rsp->session.payloadtype ==
|
||||
/*
|
||||
* Open Response
|
||||
*/
|
||||
else if (rsp->session.payloadtype ==
|
||||
IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE)
|
||||
{
|
||||
if (session->v2_data.session_state !=
|
||||
@ -621,7 +628,11 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
||||
break;
|
||||
}
|
||||
|
||||
else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_2)
|
||||
|
||||
/*
|
||||
* RAKP 2
|
||||
*/
|
||||
else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_2)
|
||||
{
|
||||
if (session->v2_data.session_state != LANPLUS_STATE_RAKP_1_SENT)
|
||||
{
|
||||
@ -634,6 +645,10 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* RAKP 4
|
||||
*/
|
||||
else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_4)
|
||||
{
|
||||
if (session->v2_data.session_state != LANPLUS_STATE_RAKP_3_SENT)
|
||||
@ -647,7 +662,11 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)
|
||||
break;
|
||||
}
|
||||
|
||||
else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)
|
||||
|
||||
/*
|
||||
* SOL
|
||||
*/
|
||||
else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)
|
||||
{
|
||||
int payload_start = offset;
|
||||
int extra_data_length;
|
||||
@ -1833,6 +1852,8 @@ struct ipmi_rs *
|
||||
|
||||
|
||||
while (try < IPMI_LAN_RETRY) {
|
||||
|
||||
|
||||
if (ipmi_lan_send_packet(intf, msg_data, msg_length) < 0) {
|
||||
printf("ipmi_lan_send_cmd failed\n");
|
||||
return NULL;
|
||||
@ -1859,13 +1880,38 @@ struct ipmi_rs *
|
||||
|
||||
if (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL)
|
||||
{
|
||||
// jme : todo. If the payload is not an ACK we need to wait
|
||||
// for an ack. And if we don't receive an ACK, we need to
|
||||
// resend.
|
||||
break;
|
||||
//if (! payload->payload.sol_packet.packet_sequence_number)
|
||||
//{
|
||||
/* This was just an ACK. We can leave now. No retry. */
|
||||
break;
|
||||
//}
|
||||
|
||||
|
||||
//int try_count = 1;
|
||||
|
||||
|
||||
// jme : todo. We need to wait for an ack. And if we
|
||||
// don't receive an ACK, we need to resend.
|
||||
|
||||
/* We need an ACK */
|
||||
//for (try_count = 1; try_count < 3; ++try_count)
|
||||
//{
|
||||
// rsp = ipmi_lan_poll_recv(intf);
|
||||
|
||||
/* Sets our last see */
|
||||
// handleIncomingSolPacket(rsp);
|
||||
|
||||
// if (acksPacket(rsp, payload))
|
||||
// break;
|
||||
//}
|
||||
|
||||
//break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This call is NOT made for SOL packets
|
||||
*/
|
||||
rsp = ipmi_lan_poll_recv(intf);
|
||||
if (rsp)
|
||||
break;
|
||||
@ -1887,9 +1933,11 @@ struct ipmi_rs *
|
||||
* return 0 on success
|
||||
* -1 on error
|
||||
*/
|
||||
int ipmi_lanplus_send_sol(struct ipmi_intf * intf,
|
||||
struct ipmi_v2_payload * v2_payload)
|
||||
struct ipmi_rs * ipmi_lanplus_send_sol(struct ipmi_intf * intf,
|
||||
struct ipmi_v2_payload * v2_payload)
|
||||
{
|
||||
struct ipmi_rs * rs;
|
||||
|
||||
v2_payload->payload_type = IPMI_PAYLOAD_TYPE_SOL;
|
||||
|
||||
/*
|
||||
@ -1907,27 +1955,100 @@ int ipmi_lanplus_send_sol(struct ipmi_intf * intf,
|
||||
|
||||
v2_payload->payload.sol_packet.accepted_character_count = 0; /* NA */
|
||||
|
||||
ipmi_lanplus_send_payload(intf, v2_payload);
|
||||
rs = ipmi_lanplus_send_payload(intf, v2_payload);
|
||||
|
||||
return 0;
|
||||
return rs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ipmi_lanplus_recv_sol
|
||||
* check_sol_packet_for_new_data
|
||||
*
|
||||
* Receive a SOL packet and send an ACK in response.
|
||||
* Determine whether the SOL packet has already been seen
|
||||
* and whether the packet has new data for us.
|
||||
*
|
||||
* This function has the side effect of removing an previously
|
||||
* seen data, and moving new data to the front.
|
||||
*
|
||||
* It also "Remembers" the data so we don't get repeats.
|
||||
*
|
||||
* returns the number of new bytes in the SOL packet
|
||||
*/
|
||||
struct ipmi_rs * ipmi_lanplus_recv_sol(struct ipmi_intf * intf)
|
||||
static int check_sol_packet_for_new_data(struct ipmi_intf * intf,
|
||||
struct ipmi_rs *rsp)
|
||||
{
|
||||
struct ipmi_v2_payload ack;
|
||||
struct ipmi_rs * rsp = ipmi_lan_poll_recv(intf);
|
||||
|
||||
/* If the SOL packet looks good, ACK it */
|
||||
if (rsp && rsp->data_len)
|
||||
static unsigned char last_received_sequence_number = 0;
|
||||
static unsigned char last_received_byte_count = 0;
|
||||
int new_data_size = 0;
|
||||
|
||||
|
||||
if (rsp &&
|
||||
(rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) &&
|
||||
(rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL))
|
||||
{
|
||||
/* Store the data length before we mod it */
|
||||
unsigned char unaltered_data_len = rsp->data_len;
|
||||
|
||||
|
||||
if (rsp->payload.sol_packet.packet_sequence_number ==
|
||||
last_received_sequence_number)
|
||||
{
|
||||
|
||||
/*
|
||||
* This is the same as the last packet, but may include
|
||||
* extra data
|
||||
*/
|
||||
new_data_size =
|
||||
rsp->data_len -
|
||||
intf->session->sol_data.last_received_byte_count;
|
||||
|
||||
if (new_data_size > 0)
|
||||
{
|
||||
/* We have more data to process */
|
||||
memmove(rsp->data,
|
||||
rsp->data +
|
||||
rsp->data_len - new_data_size,
|
||||
new_data_size);
|
||||
}
|
||||
|
||||
rsp->data_len = new_data_size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*Rember the data for next round
|
||||
*/
|
||||
if (rsp->payload.sol_packet.packet_sequence_number)
|
||||
{
|
||||
last_received_sequence_number =
|
||||
rsp->payload.sol_packet.packet_sequence_number;
|
||||
|
||||
last_received_byte_count = unaltered_data_len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new_data_size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ack_sol_packet
|
||||
*
|
||||
* Provided the specified packet looks reasonable, ACK it.
|
||||
*/
|
||||
static void ack_sol_packet(struct ipmi_intf * intf,
|
||||
struct ipmi_rs * rsp)
|
||||
{
|
||||
if (rsp &&
|
||||
(rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) &&
|
||||
(rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) &&
|
||||
(rsp->payload.sol_packet.packet_sequence_number))
|
||||
{
|
||||
struct ipmi_v2_payload ack;
|
||||
|
||||
bzero(&ack, sizeof(struct ipmi_v2_payload));
|
||||
|
||||
ack.payload_type = IPMI_PAYLOAD_TYPE_SOL;
|
||||
@ -1948,45 +2069,33 @@ struct ipmi_rs * ipmi_lanplus_recv_sol(struct ipmi_intf * intf)
|
||||
|
||||
ipmi_lanplus_send_payload(intf, &ack);
|
||||
}
|
||||
}
|
||||
|
||||
/* This may be an identical packet */
|
||||
if (rsp &&
|
||||
(rsp->payload.sol_packet.packet_sequence_number ==
|
||||
intf->session->sol_data.last_received_sequence_number))
|
||||
{
|
||||
/* This is the same as the last packet, but may include
|
||||
extra data */
|
||||
int extra_data_size =
|
||||
rsp->data_len -
|
||||
intf->session->sol_data.last_received_byte_count;
|
||||
|
||||
if (extra_data_size > 0)
|
||||
{
|
||||
/* We have more data to process */
|
||||
memmove(rsp->data,
|
||||
rsp->data +
|
||||
rsp->data_len - extra_data_size,
|
||||
extra_data_size);
|
||||
}
|
||||
|
||||
rsp->data_len = extra_data_size;
|
||||
}
|
||||
|
||||
/* If it's not an ACK, remember that we saw it. */
|
||||
if (rsp &&
|
||||
rsp->payload.sol_packet.packet_sequence_number)
|
||||
{
|
||||
intf->session->sol_data.last_received_sequence_number =
|
||||
rsp->payload.sol_packet.packet_sequence_number;
|
||||
|
||||
intf->session->sol_data.last_received_byte_count =
|
||||
rsp->data_len;
|
||||
}
|
||||
/*
|
||||
* ipmi_lanplus_recv_sol
|
||||
*
|
||||
* Receive a SOL packet and send an ACK in response.
|
||||
*
|
||||
*/
|
||||
struct ipmi_rs * ipmi_lanplus_recv_sol(struct ipmi_intf * intf)
|
||||
{
|
||||
struct ipmi_rs * rsp = ipmi_lan_poll_recv(intf);
|
||||
|
||||
ack_sol_packet(intf, rsp);
|
||||
|
||||
/*
|
||||
* Remembers the data sent, and alters the data to just
|
||||
* include the new stuff.
|
||||
*/
|
||||
check_sol_packet_for_new_data(intf, rsp);
|
||||
|
||||
return rsp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ipmi_lanplus_send_ipmi_cmd
|
||||
*
|
||||
@ -2005,7 +2114,6 @@ struct ipmi_rs *
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ipmi_get_auth_capabilities_cmd
|
||||
*
|
||||
@ -2584,8 +2692,8 @@ int ipmi_lanplus_open(struct ipmi_intf * intf)
|
||||
session->v2_data.console_id = 0x00;
|
||||
session->v2_data.bmc_id = 0x00;
|
||||
session->sol_data.sequence_number = 1;
|
||||
session->sol_data.last_received_sequence_number = 0;
|
||||
session->sol_data.last_received_byte_count = 0;
|
||||
//session->sol_data.last_received_sequence_number = 0;
|
||||
//session->sol_data.last_received_byte_count = 0;
|
||||
memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE);
|
||||
memset(session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user