1 /* 2 * media.c TIPC link functionality. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * 9 * Authors: Richard Alpe <richard.alpe (at) ericsson.com> 10 */ 11 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include <errno.h> 16 17 #include <linux/tipc_netlink.h> 18 #include <linux/tipc.h> 19 #include <linux/genetlink.h> 20 #include <libmnl/libmnl.h> 21 22 #include "cmdl.h" 23 #include "msg.h" 24 #include "media.h" 25 26 static int media_list_cb(const struct nlmsghdr *nlh, void *data) 27 { 28 struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); 29 struct nlattr *info[TIPC_NLA_MAX + 1] = {}; 30 struct nlattr *attrs[TIPC_NLA_MEDIA_MAX + 1] = {}; 31 32 mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); 33 if (!info[TIPC_NLA_MEDIA]) 34 return MNL_CB_ERROR; 35 36 mnl_attr_parse_nested(info[TIPC_NLA_MEDIA], parse_attrs, attrs); 37 if (!attrs[TIPC_NLA_MEDIA_NAME]) 38 return MNL_CB_ERROR; 39 40 printf("%s\n", mnl_attr_get_str(attrs[TIPC_NLA_MEDIA_NAME])); 41 42 return MNL_CB_OK; 43 } 44 45 static int cmd_media_list(struct nlmsghdr *nlh, const struct cmd *cmd, 46 struct cmdl *cmdl, void *data) 47 { 48 char buf[MNL_SOCKET_BUFFER_SIZE]; 49 50 if (help_flag) { 51 fprintf(stderr, "Usage: %s media list\n", cmdl->argv[0]); 52 return -EINVAL; 53 } 54 55 if (!(nlh = msg_init(buf, TIPC_NL_MEDIA_GET))) { 56 fprintf(stderr, "error, message initialisation failed\n"); 57 return -1; 58 } 59 60 return msg_dumpit(nlh, media_list_cb, NULL); 61 } 62 63 static int media_get_cb(const struct nlmsghdr *nlh, void *data) 64 { 65 int *prop = data; 66 struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); 67 struct nlattr *info[TIPC_NLA_MAX + 1] = {}; 68 struct nlattr *attrs[TIPC_NLA_MEDIA_MAX + 1] = {}; 69 struct nlattr *props[TIPC_NLA_PROP_MAX + 1] = {}; 70 71 mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); 72 if (!info[TIPC_NLA_MEDIA]) 73 return MNL_CB_ERROR; 74 75 mnl_attr_parse_nested(info[TIPC_NLA_MEDIA], parse_attrs, attrs); 76 if (!attrs[TIPC_NLA_MEDIA_PROP]) 77 return MNL_CB_ERROR; 78 79 mnl_attr_parse_nested(attrs[TIPC_NLA_MEDIA_PROP], parse_attrs, props); 80 if (!props[*prop]) 81 return MNL_CB_ERROR; 82 83 printf("%u\n", mnl_attr_get_u32(props[*prop])); 84 85 return MNL_CB_OK; 86 } 87 88 static int cmd_media_get_prop(struct nlmsghdr *nlh, const struct cmd *cmd, 89 struct cmdl *cmdl, void *data) 90 { 91 int prop; 92 char buf[MNL_SOCKET_BUFFER_SIZE]; 93 struct nlattr *nest; 94 struct opt *opt; 95 struct opt opts[] = { 96 { "media", NULL }, 97 { NULL } 98 }; 99 100 if (strcmp(cmd->cmd, "priority") == 0) 101 prop = TIPC_NLA_PROP_PRIO; 102 else if ((strcmp(cmd->cmd, "tolerance") == 0)) 103 prop = TIPC_NLA_PROP_TOL; 104 else if ((strcmp(cmd->cmd, "window") == 0)) 105 prop = TIPC_NLA_PROP_WIN; 106 else 107 return -EINVAL; 108 109 if (help_flag) { 110 (cmd->help)(cmdl); 111 return -EINVAL; 112 } 113 114 if (parse_opts(opts, cmdl) < 0) 115 return -EINVAL; 116 117 if (!(nlh = msg_init(buf, TIPC_NL_MEDIA_GET))) { 118 fprintf(stderr, "error, message initialisation failed\n"); 119 return -1; 120 } 121 122 if (!(opt = get_opt(opts, "media"))) { 123 fprintf(stderr, "error, missing media\n"); 124 return -EINVAL; 125 } 126 nest = mnl_attr_nest_start(nlh, TIPC_NLA_MEDIA); 127 mnl_attr_put_strz(nlh, TIPC_NLA_MEDIA_NAME, opt->val); 128 mnl_attr_nest_end(nlh, nest); 129 130 return msg_doit(nlh, media_get_cb, &prop); 131 } 132 133 static void cmd_media_get_help(struct cmdl *cmdl) 134 { 135 fprintf(stderr, "Usage: %s media get PPROPERTY media MEDIA\n\n" 136 "PROPERTIES\n" 137 " tolerance - Get media tolerance\n" 138 " priority - Get media priority\n" 139 " window - Get media window\n", 140 cmdl->argv[0]); 141 } 142 143 static int cmd_media_get(struct nlmsghdr *nlh, const struct cmd *cmd, 144 struct cmdl *cmdl, void *data) 145 { 146 const struct cmd cmds[] = { 147 { "priority", cmd_media_get_prop, cmd_media_get_help }, 148 { "tolerance", cmd_media_get_prop, cmd_media_get_help }, 149 { "window", cmd_media_get_prop, cmd_media_get_help }, 150 { NULL } 151 }; 152 153 return run_cmd(nlh, cmd, cmds, cmdl, NULL); 154 } 155 156 static void cmd_media_set_help(struct cmdl *cmdl) 157 { 158 fprintf(stderr, "Usage: %s media set PPROPERTY media MEDIA\n\n" 159 "PROPERTIES\n" 160 " tolerance TOLERANCE - Set media tolerance\n" 161 " priority PRIORITY - Set media priority\n" 162 " window WINDOW - Set media window\n", 163 cmdl->argv[0]); 164 } 165 166 static int cmd_media_set_prop(struct nlmsghdr *nlh, const struct cmd *cmd, 167 struct cmdl *cmdl, void *data) 168 { 169 int val; 170 int prop; 171 char buf[MNL_SOCKET_BUFFER_SIZE]; 172 struct nlattr *props; 173 struct nlattr *attrs; 174 struct opt *opt; 175 struct opt opts[] = { 176 { "media", NULL }, 177 { NULL } 178 }; 179 180 if (strcmp(cmd->cmd, "priority") == 0) 181 prop = TIPC_NLA_PROP_PRIO; 182 else if ((strcmp(cmd->cmd, "tolerance") == 0)) 183 prop = TIPC_NLA_PROP_TOL; 184 else if ((strcmp(cmd->cmd, "window") == 0)) 185 prop = TIPC_NLA_PROP_WIN; 186 else 187 return -EINVAL; 188 189 if (help_flag) { 190 (cmd->help)(cmdl); 191 return -EINVAL; 192 } 193 194 if (cmdl->optind >= cmdl->argc) { 195 fprintf(stderr, "error, missing value\n"); 196 return -EINVAL; 197 } 198 val = atoi(shift_cmdl(cmdl)); 199 200 if (parse_opts(opts, cmdl) < 0) 201 return -EINVAL; 202 203 if (!(nlh = msg_init(buf, TIPC_NL_MEDIA_SET))) { 204 fprintf(stderr, "error, message initialisation failed\n"); 205 return -1; 206 } 207 attrs = mnl_attr_nest_start(nlh, TIPC_NLA_MEDIA); 208 209 if (!(opt = get_opt(opts, "media"))) { 210 fprintf(stderr, "error, missing media\n"); 211 return -EINVAL; 212 } 213 mnl_attr_put_strz(nlh, TIPC_NLA_MEDIA_NAME, opt->val); 214 215 props = mnl_attr_nest_start(nlh, TIPC_NLA_MEDIA_PROP); 216 mnl_attr_put_u32(nlh, prop, val); 217 mnl_attr_nest_end(nlh, props); 218 219 mnl_attr_nest_end(nlh, attrs); 220 221 return msg_doit(nlh, NULL, NULL); 222 } 223 224 static int cmd_media_set(struct nlmsghdr *nlh, const struct cmd *cmd, 225 struct cmdl *cmdl, void *data) 226 { 227 const struct cmd cmds[] = { 228 { "priority", cmd_media_set_prop, cmd_media_set_help }, 229 { "tolerance", cmd_media_set_prop, cmd_media_set_help }, 230 { "window", cmd_media_set_prop, cmd_media_set_help }, 231 { NULL } 232 }; 233 234 return run_cmd(nlh, cmd, cmds, cmdl, NULL); 235 } 236 237 void cmd_media_help(struct cmdl *cmdl) 238 { 239 fprintf(stderr, 240 "Usage: %s media COMMAND [ARGS] ...\n" 241 "\n" 242 "Commands:\n" 243 " list - List active media types\n" 244 " get - Get various media properties\n" 245 " set - Set various media properties\n", 246 cmdl->argv[0]); 247 } 248 249 int cmd_media(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl, 250 void *data) 251 { 252 const struct cmd cmds[] = { 253 { "get", cmd_media_get, cmd_media_get_help }, 254 { "list", cmd_media_list, NULL }, 255 { "set", cmd_media_set, cmd_media_set_help }, 256 { NULL } 257 }; 258 259 return run_cmd(nlh, cmd, cmds, cmdl, NULL); 260 } 261