xref: /aosp_15_r20/external/iw/sar.c (revision 92022041c981f431db0b590d0c3272306d0ea2a2)
1 #include <errno.h>
2 #include <string.h>
3 
4 #include <netlink/genl/genl.h>
5 #include <netlink/msg.h>
6 #include <netlink/attr.h>
7 
8 #include "nl80211.h"
9 #include "iw.h"
10 
set_sar_specs(struct nl80211_state * state,struct nl_msg * msg,int argc,char ** argv,enum id_input id)11 static int set_sar_specs(struct nl80211_state *state,
12 			 struct nl_msg *msg,
13 			 int argc, char **argv,
14 			 enum id_input id)
15 {
16 	struct nlattr *nl_sar, *nl_specs, *nl_sub;
17 	enum nl80211_sar_type type;
18 	__u32 idx;
19 	__s32 pwr;
20 	char *tmp;
21 	int count, i;
22 
23 	if (argc <= 1)
24 		return -EINVAL;
25 
26 	type = atoi(argv[0]);
27 
28 	nl_sar = nla_nest_start(msg, NL80211_ATTR_SAR_SPEC);
29 	if (!nl_sar)
30 		goto nla_put_failure;
31 
32 	NLA_PUT_U32(msg, NL80211_SAR_ATTR_TYPE, type);
33 
34 	nl_specs = nla_nest_start(msg, NL80211_SAR_ATTR_SPECS);
35 	if (!nl_specs)
36 		goto nla_put_failure;
37 
38 	for (i = 1; i < argc; i++) {
39 		tmp = strchr(argv[i], ':');
40 		if (!tmp)
41 			return -EINVAL;
42 
43 		if (tmp != strrchr(argv[i], ':'))
44 			return -EINVAL;
45 
46 		count = sscanf(argv[i], "%u:%d", &idx, &pwr);
47 		if (count != 2)
48 			return -EINVAL;
49 
50 		nl_sub = nla_nest_start(msg, i - 1);
51 		if (!nl_sub)
52 			goto nla_put_failure;
53 
54 		NLA_PUT_U32(msg, NL80211_SAR_ATTR_SPECS_RANGE_INDEX, idx);
55 		NLA_PUT_S32(msg, NL80211_SAR_ATTR_SPECS_POWER, pwr);
56 
57 		nla_nest_end(msg, nl_sub);
58 	}
59 
60 	nla_nest_end(msg, nl_specs);
61 	nla_nest_end(msg, nl_sar);
62 
63 	return 0;
64 
65  nla_put_failure:
66 	return -ENOBUFS;
67 }
68 
69 COMMAND(set, sar_specs, "<sar type> <range index:sar power>*",
70 	NL80211_CMD_SET_SAR_SPECS, 0, CIB_PHY, set_sar_specs,
71 	"Set SAR specs corresponding to SAR capa of wiphy.");
72