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@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
media_list_cb(const struct nlmsghdr * nlh,void * data)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
cmd_media_list(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)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
media_get_cb(const struct nlmsghdr * nlh,void * data)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
cmd_media_get_prop(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)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
cmd_media_get_help(struct cmdl * cmdl)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
cmd_media_get(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)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
cmd_media_set_help(struct cmdl * cmdl)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
cmd_media_set_prop(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)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
cmd_media_set(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)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
cmd_media_help(struct cmdl * cmdl)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
cmd_media(struct nlmsghdr * nlh,const struct cmd * cmd,struct cmdl * cmdl,void * data)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