Relicense to ISC License.
[routeros-api.git] / src / registration_table.c
1 /**
2  * librouteros - src/registration_table.c
3  * Copyright (C) 2009  Florian octo Forster
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
14  * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  *
17  * Authors:
18  *   Florian octo Forster <octo at verplant.org>
19  **/
20
21 #ifndef _ISOC99_SOURCE
22 # define _ISOC99_SOURCE
23 #endif
24
25 #ifndef _POSIX_C_SOURCE
26 # define _POSIX_C_SOURCE 200112L
27 #endif
28
29 #include "config.h"
30
31 #include <stdlib.h>
32 #include <math.h>
33 #include <errno.h>
34 #include <string.h>
35 #include <stdint.h>
36 #include <inttypes.h>
37 #include <assert.h>
38
39 #include "routeros_api.h"
40 #include "ros_parse.h"
41
42 /*
43 Status: re
44   Param 0: .id = *C
45   Param 1: interface = wlan2
46   Param 2: radio-name = 000C423AECCF
47   Param 3: mac-address = 00:0C:42:3A:EC:CF
48   Param 4: ap = true
49   Param 5: wds = false
50   Param 6: rx-rate = 58.5Mbps-HT
51   Param 7: tx-rate = 52.0Mbps-HT
52   Param 8: packets = 6962070,10208268
53   Param 9: bytes = 1090924066,2872515632
54   Param 10: frames = 6662813,9698341
55   Param 11: frame-bytes = 1111022872,2846535122
56   Param 12: hw-frames = 8338229,9718084
57   Param 13: hw-frame-bytes = 1941643579,3255546365
58   Param 14: tx-frames-timed-out = 0
59   Param 15: uptime = 2w6d13:21:53
60   Param 16: last-activity = 00:00:00.060
61   Param 17: signal-strength = -74dBm@6Mbps
62   Param 18: signal-to-noise = 42
63   Param 19: strength-at-rates = -74dBm@6Mbps 10ms,-78dBm@9Mbps 2w2d16h56m20s890ms,-78dBm@12Mbps 2w2d16h55m51s670ms,-77dBm@18Mbps 2w2d16h55m35s880ms,-78dBm@24Mbps 2w2d16h55m5s590ms,-75dBm@36Mbps 1d10h58m48s840ms,-75dBm@48Mbps 1d10h48m34s130ms,-77dBm@54Mbps 1d10h47m34s680ms,-73dBm@HT20-4 38m45s600ms,-73dBm@HT20-5 4m700ms,-74dBm@HT20-6 60ms,-78dBm@HT20-7 1d10h30m34s410ms
64   Param 20: tx-signal-strength = -76
65   Param 21: tx-ccq = 51
66   Param 22: rx-ccq = 77
67   Param 23: p-throughput = 36877
68   Param 24: ack-timeout = 30
69   Param 25: nstreme = false
70   Param 26: framing-mode = none
71   Param 27: routeros-version = 4.2
72   Param 28: last-ip = 62.128.1.53
73   Param 29: 802.1x-port-enabled = true
74   Param 30: authentication-type = wpa2-psk
75   Param 31: encryption = aes-ccm
76   Param 32: group-encryption = aes-ccm
77   Param 33: compression = false
78   Param 34: wmm-enabled = true
79 ===
80 Status: done
81 ===
82  */
83
84 /*
85  * Private data types
86  */
87 struct rt_internal_data_s
88 {
89         ros_registration_table_handler_t handler;
90         void *user_data;
91 };
92 typedef struct rt_internal_data_s rt_internal_data_t;
93
94 /*
95  * Private functions
96  */
97 static ros_registration_table_t *rt_reply_to_regtable (const ros_reply_t *r) /* {{{ */
98 {
99         ros_registration_table_t *ret;
100
101         if (r == NULL)
102                 return (NULL);
103
104         if (strcmp ("re", ros_reply_status (r)) != 0)
105                 return (rt_reply_to_regtable (ros_reply_next (r)));
106
107         ret = malloc (sizeof (*ret));
108         if (ret == NULL)
109                 return (NULL);
110         memset (ret, 0, sizeof (*ret));
111
112         ret->interface = ros_reply_param_val_by_key (r, "interface");
113         ret->radio_name = ros_reply_param_val_by_key (r, "radio-name");
114
115         ret->ap = sstrtob (ros_reply_param_val_by_key (r, "ap"));
116         ret->wds = sstrtob (ros_reply_param_val_by_key (r, "wds"));
117
118         ret->rx_rate = sstrtod (ros_reply_param_val_by_key (r, "rx-rate"));
119         ret->tx_rate = sstrtod (ros_reply_param_val_by_key (r, "tx-rate"));
120
121         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "packets"),
122                         &ret->rx_packets, &ret->tx_packets);
123         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "bytes"),
124                         &ret->rx_bytes, &ret->tx_bytes);
125         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "frames"),
126                         &ret->rx_frames, &ret->tx_frames);
127         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "frame-bytes"),
128                         &ret->rx_frame_bytes, &ret->tx_frame_bytes);
129         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "hw-frames"),
130                         &ret->rx_hw_frames, &ret->tx_hw_frames);
131         sstrto_rx_tx_counters (ros_reply_param_val_by_key (r, "hw-frame-bytes"),
132                         &ret->rx_hw_frame_bytes, &ret->tx_hw_frame_bytes);
133
134         ret->rx_signal_strength = sstrtod (ros_reply_param_val_by_key (r, "signal-strength"));
135         ret->tx_signal_strength = sstrtod (ros_reply_param_val_by_key (r, "tx-signal-strength"));
136         ret->signal_to_noise = sstrtod (ros_reply_param_val_by_key (r, "signal-to-noise"));
137
138         ret->rx_ccq = sstrtod (ros_reply_param_val_by_key (r, "rx-ccq"));
139         ret->tx_ccq = sstrtod (ros_reply_param_val_by_key (r, "tx-ccq"));
140
141         ret->next = rt_reply_to_regtable (ros_reply_next (r));
142
143         return (ret);
144 } /* }}} ros_registration_table_t *rt_reply_to_regtable */
145
146 static void rt_regtable_free (const ros_registration_table_t *r) /* {{{ */
147 {
148         const ros_registration_table_t *next;
149
150         while (r != NULL)
151         {
152                 next = r->next;
153                 free ((void *) r);
154                 r = next;
155         }
156 } /* }}} void rt_regtable_free */
157
158 static int rt_internal_handler (ros_connection_t *c, /* {{{ */
159                 const ros_reply_t *r, void *user_data)
160 {
161         ros_registration_table_t *rt_data;
162         rt_internal_data_t *internal_data;
163         int status;
164
165         rt_data = rt_reply_to_regtable (r);
166         if (rt_data == NULL)
167                 return (errno);
168
169         internal_data = user_data;
170
171         status = internal_data->handler (c, rt_data, internal_data->user_data);
172
173         rt_regtable_free (rt_data);
174
175         return (status);
176 } /* }}} int rt_internal_handler */
177
178 /*
179  * Public functions
180  */
181 int ros_registration_table (ros_connection_t *c, /* {{{ */
182                 ros_registration_table_handler_t handler, void *user_data)
183 {
184         rt_internal_data_t data;
185
186         if ((c == NULL) || (handler == NULL))
187                 return (EINVAL);
188
189         data.handler = handler;
190         data.user_data = user_data;
191
192         return (ros_query (c, "/interface/wireless/registration-table/print",
193                                 /* args_num = */ 0, /* args = */ NULL,
194                                 rt_internal_handler, &data));
195 } /* }}} int ros_registration_table */
196
197 /* vim: set ts=2 sw=2 noet fdm=marker : */