void IPMI_handler()

in common/ipmi/ipmi.c [284:427]


void IPMI_handler(void *arug0, void *arug1, void *arug2)
{
	uint8_t i;
	ipmi_msg_cfg msg_cfg;

	while (1) {
		k_msgq_get(&ipmi_msgq, &msg_cfg, K_FOREVER);

		if (DEBUG_IPMI) {
			printf("IPMI_handler[%d]: netfn: %x\n", msg_cfg.buffer.data_len,
			       msg_cfg.buffer.netfn);
			for (i = 0; i < msg_cfg.buffer.data_len; i++) {
				printf(" 0x%2x", msg_cfg.buffer.data[i]);
			}
			printf("\n");
		}

		msg_cfg.buffer.completion_code = CC_INVALID_CMD;
		switch (msg_cfg.buffer.netfn) {
		case NETFN_CHASSIS_REQ:
			IPMI_CHASSIS_handler(&msg_cfg.buffer);
			break;
		case NETFN_BRIDGE_REQ:
			// IPMI_BRIDGE_handler();
			break;
		case NETFN_SENSOR_REQ:
			IPMI_SENSOR_handler(&msg_cfg.buffer);
			break;
		case NETFN_APP_REQ:
			IPMI_APP_handler(&msg_cfg.buffer);
			break;
		case NETFN_FIRMWARE_REQ:
			break;
		case NETFN_STORAGE_REQ:
			IPMI_Storage_handler(&msg_cfg.buffer);
			break;
		case NETFN_TRANSPORT_REQ:
			break;
		case NETFN_DCMI_REQ:
			break;
		case NETFN_NM_REQ:
			break;
		case NETFN_OEM_REQ:
			IPMI_OEM_handler(&msg_cfg.buffer);
			break;
		case NETFN_OEM_1S_REQ:
			if ((msg_cfg.buffer.data[0] | (msg_cfg.buffer.data[1] << 8) |
			     (msg_cfg.buffer.data[2] << 16)) == WW_IANA_ID) {
				memcpy(&msg_cfg.buffer.data[0], &msg_cfg.buffer.data[3],
				       msg_cfg.buffer.data_len);
				msg_cfg.buffer.data_len -= 3;
				IPMI_OEM_1S_handler(&msg_cfg.buffer);
				break;
			} else if (pal_is_not_return_cmd(msg_cfg.buffer.netfn,
							 msg_cfg.buffer.cmd)) {
				msg_cfg.buffer.completion_code = CC_INVALID_IANA;
				IPMI_OEM_1S_handler(
					&msg_cfg.buffer); // Due to command not returning to bridge command source, enter command handler and return with other invalid CC
				break;
			} else {
				msg_cfg.buffer.completion_code = CC_INVALID_IANA;
				msg_cfg.buffer.data_len = 0;
				break;
			}
		default: // invalid net function
			printf("invalid msg netfn: %x, cmd: %x\n", msg_cfg.buffer.netfn,
			       msg_cfg.buffer.cmd);
			msg_cfg.buffer.data_len = 0;
			break;
		}

		if (pal_is_not_return_cmd(msg_cfg.buffer.netfn, msg_cfg.buffer.cmd)) {
			;
		} else {
			ipmb_error status;

			if (msg_cfg.buffer.completion_code != CC_SUCCESS) {
				msg_cfg.buffer.data_len = 0;
			} else if (msg_cfg.buffer.netfn == NETFN_OEM_1S_REQ) {
				uint8_t copy_data[msg_cfg.buffer.data_len];
				memcpy(&copy_data[0], &msg_cfg.buffer.data[0],
				       msg_cfg.buffer.data_len);
				memcpy(&msg_cfg.buffer.data[3], &copy_data[0],
				       msg_cfg.buffer.data_len);
				msg_cfg.buffer.data_len += 3;
				msg_cfg.buffer.data[0] = WW_IANA_ID & 0xFF;
				msg_cfg.buffer.data[1] = (WW_IANA_ID >> 8) & 0xFF;
				msg_cfg.buffer.data[2] = (WW_IANA_ID >> 16) & 0xFF;
			}

			if (msg_cfg.buffer.InF_source == BMC_USB_IFs) {
				USB_write(&msg_cfg.buffer);
#ifdef CONFIG_IPMI_KCS_ASPEED
			} else if (msg_cfg.buffer.InF_source == HOST_KCS_IFs) {
				uint8_t *kcs_buff;
				kcs_buff = malloc(KCS_buff_size * sizeof(uint8_t));
				if (kcs_buff == NULL) { // allocate fail, retry allocate
					k_msleep(10);
					kcs_buff = malloc(KCS_buff_size * sizeof(uint8_t));
					if (kcs_buff == NULL) {
						printk("IPMI_handler: Fail to malloc for kcs_buff\n");
						continue;
					}
				}
				kcs_buff[0] = (msg_cfg.buffer.netfn + 1)
					      << 2; // ipmi netfn response package
				kcs_buff[1] = msg_cfg.buffer.cmd;
				kcs_buff[2] = msg_cfg.buffer.completion_code;
				if (msg_cfg.buffer.data_len) {
					if (msg_cfg.buffer.data_len <= (KCS_buff_size - 3))
						memcpy(&kcs_buff[3], msg_cfg.buffer.data,
						       msg_cfg.buffer.data_len);
					else
						memcpy(&kcs_buff[3], msg_cfg.buffer.data,
						       (KCS_buff_size - 3));
				}

				if (DEBUG_KCS) {
					printk("kcs from ipmi netfn %x, cmd %x, length %d, cc %x\n",
					       kcs_buff[0], kcs_buff[1], msg_cfg.buffer.data_len,
					       kcs_buff[2]);
				}

				kcs_write(kcs_buff, msg_cfg.buffer.data_len + 3);

				if (kcs_buff != NULL)
					free(kcs_buff);
#endif
			} else if (msg_cfg.buffer.InF_source == PLDM_IFs) {
				/* the message should be passed to source by pldm
                           * format */
				send_msg_by_pldm(&msg_cfg);
			} else {
				status = ipmb_send_response(
					&msg_cfg.buffer,
					IPMB_inf_index_map[msg_cfg.buffer.InF_source]);
				if (status != ipmb_error_success) {
					printf("IPMI_handler send IPMB resp fail status: %x",
					       status);
				}
			}
		}
	}
}