in common/mctp/mctp.c [230:332]
static void mctp_tx_task(void *arg, void *dummy0, void *dummy1)
{
ARG_UNUSED(dummy0);
ARG_UNUSED(dummy1);
if (!arg) {
LOG_WRN("mctp_tx_task without mctp_inst!");
return;
}
mctp *mctp_inst = (mctp *)arg;
if (!mctp_inst->write_data) {
LOG_WRN("mctp_tx_task without medium write function!");
return;
}
LOG_INF("mctp_tx_task start %p ", mctp_inst);
while (1) {
mctp_tx_msg mctp_msg = { 0 };
int ret = k_msgq_get(&mctp_inst->mctp_tx_queue, &mctp_msg, K_FOREVER);
if (ret)
continue;
if (!mctp_msg.buf)
continue;
if (!mctp_msg.len) {
free(mctp_msg.buf);
continue;
}
LOG_DBG("tx endpoint %x", mctp_msg.ext_params.ep);
LOG_HEXDUMP_DBG(mctp_msg.buf, mctp_msg.len, "mctp tx task receive data");
/*
* The bridge meesage already has the mctp transport header, and the bridge
* message also doesn't need to split packet.
*/
if (mctp_msg.is_bridge_packet) {
mctp_inst->write_data(mctp_inst, mctp_msg.buf, mctp_msg.len,
mctp_msg.ext_params);
free(mctp_msg.buf);
continue;
}
/* Setup MCTP header and send to destination endpoint */
static uint8_t msg_tag;
uint16_t max_msg_size = mctp_inst->max_msg_size;
uint8_t i;
uint8_t split_pkt_num =
(mctp_msg.len / max_msg_size) + ((mctp_msg.len % max_msg_size) ? 1 : 0);
LOG_DBG("mctp_msg.len = %d", mctp_msg.len);
LOG_DBG("split_pkt_num = %d", split_pkt_num);
for (i = 0; i < split_pkt_num; i++) {
uint8_t buf[max_msg_size + MCTP_TRANSPORT_HEADER_SIZE];
mctp_hdr *hdr = (mctp_hdr *)buf;
uint8_t cp_msg_size = max_msg_size;
memset(buf, 0, sizeof(buf));
/* The first packet should set SOM */
if (!i)
hdr->som = 1;
/* The last packet should set EOM */
if (i == (split_pkt_num - 1)) {
hdr->eom = 1;
uint8_t remain = mctp_msg.len % max_msg_size;
cp_msg_size = remain ? remain : max_msg_size; /* remain data */
}
hdr->to = mctp_msg.ext_params.tag_owner;
hdr->pkt_seq = i & MCTP_HDR_SEQ_MASK;
/*
* TODO: should avoid the msg_tag if there are pending mctp
* response packets?
* If the message is response, keep the original msg_tag of ext_params
*/
hdr->msg_tag = (hdr->to) ? (msg_tag & MCTP_HDR_TAG_MASK) :
mctp_msg.ext_params.msg_tag;
hdr->dest_ep = mctp_msg.ext_params.ep;
hdr->src_ep = mctp_inst->endpoint;
hdr->hdr_ver = MCTP_HDR_HDR_VER;
LOG_DBG("i = %d, cp_msg_size = %d", i, cp_msg_size);
LOG_DBG("hdr->flags_seq_to_tag = %x", hdr->flags_seq_to_tag);
memcpy(buf + MCTP_TRANSPORT_HEADER_SIZE, mctp_msg.buf + i * max_msg_size,
cp_msg_size);
mctp_inst->write_data(mctp_inst, buf,
cp_msg_size + MCTP_TRANSPORT_HEADER_SIZE,
mctp_msg.ext_params);
}
free(mctp_msg.buf);
/* Only request mctp message needs to increase msg_tag */
if (mctp_msg.ext_params.tag_owner)
msg_tag++;
}
}