Skip to content

Commit e55310e

Browse files
committed
GetMsgType : Take from config
GetMsgType response is hardcoded and always return only control message support. Read supported message types from config file and reply in control message Tested by sending GetMsgType and GetVersion from another EP Default responses for GetMsgType and GetVersion for type 0 5, 0, 1, 0 and 4, 0, 4, 241, 240, 255, 0, 241, 241, 255, 0, 241, 242, 255, 0, 241, 243, 241, 0 After calling busctl call au.com.codeconstruct.MCTP1 /au/com/codeconstruct/mctp1 au.com.codeconstruct.MCTP1 RegisterResponder yau 5 1 0xF1F2F3F4 Response for GetMsgType and GetVersion for type 5 5, 0, 2, 0, 5 and 4, 0, 1, 244, 243, 242, 241 Signed-off-by: Nidhin MS <[email protected]>
1 parent 0d13310 commit e55310e

File tree

1 file changed

+216
-24
lines changed

1 file changed

+216
-24
lines changed

src/mctpd.c

Lines changed: 216 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,16 @@ struct peer {
192192
} recovery;
193193
};
194194

195+
struct msg_type_support {
196+
size_t count;
197+
198+
// Assume array index follows same order. Msg type at msg_types[0]
199+
// will have version_counts[0] versions stored at versions[0]
200+
uint8_t *msg_types;
201+
size_t *version_counts;
202+
uint32_t **versions;
203+
};
204+
195205
struct ctx {
196206
sd_event *event;
197207
sd_bus *bus;
@@ -219,6 +229,9 @@ struct ctx {
219229

220230
uint8_t uuid[16];
221231

232+
// Supported message types and their versions
233+
struct msg_type_support supported_msg_types;
234+
222235
// Verbose logging
223236
bool verbose;
224237
};
@@ -670,6 +683,7 @@ handle_control_get_version_support(struct ctx *ctx, int sd,
670683
// space for 4 versions
671684
uint8_t respbuf[sizeof(*resp) + 4 * sizeof(*versions)];
672685
size_t resp_len;
686+
ssize_t i, ver_idx = -1, ver_count = 0;
673687

674688
if (buf_size < sizeof(struct mctp_ctrl_cmd_get_mctp_ver_support)) {
675689
warnx("short Get Version Support message");
@@ -679,24 +693,32 @@ handle_control_get_version_support(struct ctx *ctx, int sd,
679693
req = (void *)buf;
680694
resp = (void *)respbuf;
681695
memset(resp, 0x0, sizeof(*resp));
682-
versions = (void *)(resp + 1);
683-
switch (req->msg_type_number) {
684-
case 0xff: // Base Protocol
685-
case 0x00: // Control protocol
686-
// from DSP0236 1.3.1 section 12.6.2. Big endian.
687-
versions[0] = htonl(0xF1F0FF00);
688-
versions[1] = htonl(0xF1F1FF00);
689-
versions[2] = htonl(0xF1F2FF00);
690-
versions[3] = htonl(0xF1F3F100);
691-
resp->number_of_entries = 4;
692-
resp->completion_code = MCTP_CTRL_CC_SUCCESS;
693-
resp_len = sizeof(*resp) + 4 * sizeof(*versions);
694-
break;
695-
default:
696+
if (req->msg_type_number == 0xFF) {
697+
// use same version for base spec and control protocol
698+
req->msg_type_number = 0;
699+
}
700+
for (i = 0; i < ctx->supported_msg_types.count; i++) {
701+
if (ctx->supported_msg_types.msg_types[i] ==
702+
req->msg_type_number) {
703+
ver_idx = i;
704+
break;
705+
}
706+
}
707+
if (ver_idx < 0) {
696708
// Unsupported message type
697709
resp->completion_code =
698710
MCTP_CTRL_CC_GET_MCTP_VER_SUPPORT_UNSUPPORTED_TYPE;
699-
resp_len = sizeof(*resp);
711+
// Number of enrties not needed in unsupprted cmd
712+
resp_len = sizeof(*resp) - sizeof(uint8_t);
713+
} else {
714+
versions = (void *)(resp + 1);
715+
ver_count = ctx->supported_msg_types.version_counts[ver_idx];
716+
memcpy(versions, ctx->supported_msg_types.versions[ver_idx],
717+
ver_count * sizeof(uint32_t));
718+
resp->number_of_entries = ver_count;
719+
720+
resp->completion_code = MCTP_CTRL_CC_SUCCESS;
721+
resp_len = sizeof(*resp) + ver_count * sizeof(uint32_t);
700722
}
701723

702724
resp->ctrl_hdr.command_code = req->ctrl_hdr.command_code;
@@ -761,28 +783,39 @@ static int handle_control_get_message_type_support(
761783
const uint8_t *buf, const size_t buf_size)
762784
{
763785
struct mctp_ctrl_cmd_get_msg_type_support *req = NULL;
764-
;
765786
struct mctp_ctrl_resp_get_msg_type_support *resp = NULL;
766-
uint8_t resp_buf[sizeof(*resp) + 1];
767-
size_t resp_len;
787+
uint8_t *resp_buf;
788+
size_t resp_len, type_count;
768789

769790
if (buf_size < sizeof(*req)) {
770791
warnx("short Get Message Type Support message");
771792
return -ENOMSG;
772793
}
773794

774795
req = (void *)buf;
796+
type_count = ctx->supported_msg_types.count;
797+
// Allocate extra space for the message types
798+
resp_len = sizeof(*resp) + type_count;
799+
resp_buf = malloc(resp_len);
800+
if (!resp_buf) {
801+
warnx("Failed to allocate response buffer");
802+
return -ENOMEM;
803+
}
804+
775805
resp = (void *)resp_buf;
776-
resp->ctrl_hdr.command_code = req->ctrl_hdr.command_code;
777806
resp->ctrl_hdr.rq_dgram_inst =
778807
(req->ctrl_hdr.rq_dgram_inst & IID_MASK) | RQDI_RESP;
808+
resp->ctrl_hdr.command_code = req->ctrl_hdr.command_code;
809+
resp->completion_code = MCTP_CTRL_CC_SUCCESS;
779810

780-
// Only control messages supported
781-
resp->msg_type_count = 1;
782-
*((uint8_t *)(resp + 1)) = MCTP_CTRL_HDR_MSG_TYPE;
783-
resp_len = sizeof(*resp) + resp->msg_type_count;
811+
resp->msg_type_count = type_count;
812+
// Append message types after msg_type_count
813+
memcpy((uint8_t *)(resp + 1), ctx->supported_msg_types.msg_types,
814+
type_count);
784815

785-
return reply_message(ctx, sd, resp, resp_len, addr);
816+
int result = reply_message(ctx, sd, resp, resp_len, addr);
817+
free(resp_buf);
818+
return result;
786819
}
787820

788821
static int
@@ -2829,6 +2862,91 @@ static int method_net_learn_endpoint(sd_bus_message *call, void *data,
28292862
return rc;
28302863
}
28312864

2865+
static int method_register_responder(sd_bus_message *call, void *data,
2866+
sd_bus_error *berr)
2867+
{
2868+
struct ctx *ctx = data;
2869+
uint8_t msg_type;
2870+
const uint32_t *versions = NULL;
2871+
size_t versions_len;
2872+
int rc;
2873+
int i;
2874+
2875+
rc = sd_bus_message_read(call, "y", &msg_type);
2876+
if (rc < 0)
2877+
goto err;
2878+
rc = sd_bus_message_read_array(call, 'u', (const void **)&versions,
2879+
&versions_len);
2880+
if (rc < 0)
2881+
goto err;
2882+
2883+
if (versions_len == 0) {
2884+
warnx("No versions provided for message type %d", msg_type);
2885+
return sd_bus_error_setf(
2886+
berr, SD_BUS_ERROR_INVALID_ARGS,
2887+
"No versions provided for message type %d", msg_type);
2888+
}
2889+
2890+
for (i = 0; i < ctx->supported_msg_types.count; i++) {
2891+
if (ctx->supported_msg_types.msg_types[i] == msg_type) {
2892+
warnx("Message type %d already registered", msg_type);
2893+
return sd_bus_error_setf(
2894+
berr, SD_BUS_ERROR_INVALID_ARGS,
2895+
"Message type %d already registered", msg_type);
2896+
}
2897+
}
2898+
2899+
uint8_t *msg_types =
2900+
realloc(ctx->supported_msg_types.msg_types,
2901+
(ctx->supported_msg_types.count + 1) * sizeof(uint8_t));
2902+
if (!msg_types) {
2903+
goto oom_err;
2904+
}
2905+
ctx->supported_msg_types.msg_types = msg_types;
2906+
2907+
uint32_t **versions_ptr = realloc(ctx->supported_msg_types.versions,
2908+
(ctx->supported_msg_types.count + 1) *
2909+
sizeof(uint32_t *));
2910+
if (!versions_ptr) {
2911+
// realloc ptrs are not cleared. msg_types will have one byte extra capacity.
2912+
// same for next alloc also.
2913+
goto oom_err;
2914+
}
2915+
ctx->supported_msg_types.versions = versions_ptr;
2916+
2917+
size_t *version_counts =
2918+
realloc(ctx->supported_msg_types.version_counts,
2919+
(ctx->supported_msg_types.count + 1) * sizeof(size_t));
2920+
if (!version_counts) {
2921+
goto oom_err;
2922+
}
2923+
ctx->supported_msg_types.version_counts = version_counts;
2924+
2925+
uint32_t *msg_versions = malloc(versions_len);
2926+
if (!msg_versions) {
2927+
goto oom_err;
2928+
}
2929+
// Assume callers's responsibility to provide version in uint32 format from spec
2930+
memcpy(msg_versions, versions, versions_len);
2931+
2932+
ctx->supported_msg_types.msg_types[ctx->supported_msg_types.count] =
2933+
msg_type;
2934+
ctx->supported_msg_types.versions[ctx->supported_msg_types.count] =
2935+
msg_versions;
2936+
ctx->supported_msg_types.version_counts[ctx->supported_msg_types.count] =
2937+
versions_len / sizeof(uint32_t);
2938+
ctx->supported_msg_types.count++;
2939+
2940+
return sd_bus_reply_method_return(call, "");
2941+
2942+
oom_err:
2943+
return sd_bus_error_setf(berr, SD_BUS_ERROR_NO_MEMORY,
2944+
"Failed to allocate memory");
2945+
err:
2946+
set_berr(ctx, rc, berr);
2947+
return rc;
2948+
}
2949+
28322950
// clang-format off
28332951
static const sd_bus_vtable bus_link_owner_vtable[] = {
28342952
SD_BUS_VTABLE_START(0),
@@ -3145,6 +3263,17 @@ static const sd_bus_vtable bus_network_vtable[] = {
31453263
SD_BUS_VTABLE_PROPERTY_CONST),
31463264
SD_BUS_VTABLE_END
31473265
};
3266+
3267+
static const sd_bus_vtable mctp_base_vtable[] = {
3268+
SD_BUS_VTABLE_START(0),
3269+
SD_BUS_METHOD_WITH_ARGS("RegisterResponder",
3270+
SD_BUS_ARGS("y", msg_type,
3271+
"au", versions),
3272+
SD_BUS_NO_RESULT,
3273+
method_register_responder,
3274+
0),
3275+
SD_BUS_VTABLE_END,
3276+
};
31483277
// clang-format on
31493278

31503279
static int emit_endpoint_added(const struct peer *peer)
@@ -3295,6 +3424,14 @@ static int setup_bus(struct ctx *ctx)
32953424
goto out;
32963425
}
32973426

3427+
rc = sd_bus_add_object_vtable(ctx->bus, NULL, MCTP_DBUS_PATH,
3428+
MCTP_DBUS_NAME,
3429+
mctp_base_vtable, ctx);
3430+
if (rc < 0) {
3431+
warnx("Adding MCTP base vtable failed: %s", strerror(-rc));
3432+
goto out;
3433+
}
3434+
32983435
rc = 0;
32993436
out:
33003437
return rc;
@@ -3996,13 +4133,68 @@ static int parse_config(struct ctx *ctx)
39964133

39974134
static void setup_config_defaults(struct ctx *ctx)
39984135
{
4136+
uint32_t *ctrl_cmd_versions = NULL;
4137+
ctx->supported_msg_types.msg_types = NULL;
4138+
ctx->supported_msg_types.versions = NULL;
4139+
ctx->supported_msg_types.version_counts = NULL;
4140+
39994141
ctx->mctp_timeout = 250000; // 250ms
40004142
ctx->default_role = ENDPOINT_ROLE_BUS_OWNER;
4143+
ctx->supported_msg_types.count = 0;
4144+
4145+
// Default to supporting only control messages
4146+
ctx->supported_msg_types.msg_types = malloc(1);
4147+
if (!ctx->supported_msg_types.msg_types) {
4148+
warnx("Out of memory for supported message types");
4149+
goto oom_err;
4150+
}
4151+
ctrl_cmd_versions = malloc(sizeof(uint32_t) * 4);
4152+
if (!ctrl_cmd_versions) {
4153+
warnx("Out of memory for versions");
4154+
goto oom_err;
4155+
}
4156+
ctx->supported_msg_types.versions = malloc(sizeof(uint32_t *));
4157+
if (!ctx->supported_msg_types.versions) {
4158+
warnx("Out of memory for versions");
4159+
goto oom_err;
4160+
}
4161+
ctx->supported_msg_types.version_counts = malloc(sizeof(size_t));
4162+
if (!ctx->supported_msg_types.version_counts) {
4163+
warnx("Out of memory for version counts");
4164+
goto oom_err;
4165+
}
4166+
4167+
ctx->supported_msg_types.count = 1;
4168+
ctx->supported_msg_types.msg_types[0] = MCTP_CTRL_HDR_MSG_TYPE;
4169+
ctrl_cmd_versions[0] = htonl(0xF1F0FF00);
4170+
ctrl_cmd_versions[1] = htonl(0xF1F1FF00);
4171+
ctrl_cmd_versions[2] = htonl(0xF1F2FF00);
4172+
ctrl_cmd_versions[3] = htonl(0xF1F3F100);
4173+
ctx->supported_msg_types.versions[0] = ctrl_cmd_versions;
4174+
ctx->supported_msg_types.version_counts[0] = 4;
4175+
4176+
return;
4177+
oom_err:
4178+
free(ctrl_cmd_versions);
4179+
free(ctx->supported_msg_types.msg_types);
4180+
free(ctx->supported_msg_types.versions);
4181+
free(ctx->supported_msg_types.version_counts);
4182+
ctx->supported_msg_types.msg_types = NULL;
4183+
ctx->supported_msg_types.versions = NULL;
4184+
ctx->supported_msg_types.version_counts = NULL;
40014185
}
40024186

40034187
static void free_config(struct ctx *ctx)
40044188
{
4189+
int i;
4190+
40054191
free(ctx->config_filename);
4192+
for (i = 0; i < ctx->supported_msg_types.count; i++) {
4193+
free(ctx->supported_msg_types.versions[i]);
4194+
}
4195+
free(ctx->supported_msg_types.versions);
4196+
free(ctx->supported_msg_types.version_counts);
4197+
free(ctx->supported_msg_types.msg_types);
40064198
}
40074199

40084200
int main(int argc, char **argv)

0 commit comments

Comments
 (0)