Convert to using use SPDX identifier on wsutil directory
[metze/wireshark/wip.git] / wsutil / frequency-utils.c
1 /* frequency-utils.c
2  * Frequency conversion utility definitions
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 2007 Gerald Combs
7  *
8  * SPDX-License-Identifier: GPL-2.0+
9  */
10
11 #include "config.h"
12
13 #include <glib.h>
14
15 #include "frequency-utils.h"
16
17 typedef struct freq_cvt_s {
18     guint fmin;         /* Minimum frequency in MHz */
19     guint fmax;         /* Maximum frequency in MHz */
20     gint cmin;          /* Minimum/base channel */
21     gboolean is_bg;     /* B/G channel? */
22 } freq_cvt_t;
23
24 #define FREQ_STEP 5     /* MHz. This seems to be consistent, thankfully */
25
26 /*
27  * From IEEE Std 802.11-2012:
28  *
29  *    section 16.4.6.3 "Channel Numbering of operating channels";
30  *
31  *    section 17.4.6.3 "Channel Numbering of operating channels";
32  *
33  *    section 18.3.8.4.2 "Channel numbering";
34  *
35  *    Annex E.
36  *
37  * XXX - Japanese channels 182 through 196 actually have center
38  * frequencies that are off by 2.5 MHz from these values, according
39  * to the IEEE standard, although the table in ARIB STD T-71 version 5.2:
40  *
41  *     http://www.arib.or.jp/english/html/overview/doc/1-STD-T71v5_2.pdf
42  *
43  * section 5.3.8.3.3 doesn't show that.
44  *
45  * XXX - what about the U.S. public safety 4.9 GHz band?
46  *
47  * XXX - what about 802.11ad?
48  */
49 static freq_cvt_t freq_cvt[] = {
50     { 2412, 2472,   1, TRUE },
51     { 2484, 2484,  14, TRUE },
52     { 5000, 5995,   0, FALSE },
53     { 4910, 4980, 182, FALSE }
54 };
55
56 #define NUM_FREQ_CVT (sizeof(freq_cvt) / sizeof(freq_cvt_t))
57 #define MAX_CHANNEL(fc) ( (gint) ((fc.fmax - fc.fmin) / FREQ_STEP) + fc.cmin )
58
59 /*
60  * Get channel number given a Frequency
61  */
62 gint
63 ieee80211_mhz_to_chan(guint freq) {
64     guint i;
65
66     for (i = 0; i < NUM_FREQ_CVT; i++) {
67         if (freq >= freq_cvt[i].fmin && freq <= freq_cvt[i].fmax) {
68             return ((freq - freq_cvt[i].fmin) / FREQ_STEP) + freq_cvt[i].cmin;
69         }
70     }
71     return -1;
72 }
73
74 /*
75  * Get Frequency given a Channel number
76  */
77 guint
78 ieee80211_chan_to_mhz(gint chan, gboolean is_bg) {
79     guint i;
80
81     for (i = 0; i < NUM_FREQ_CVT; i++) {
82         if (is_bg == freq_cvt[i].is_bg &&
83                 chan >= freq_cvt[i].cmin && chan <= MAX_CHANNEL(freq_cvt[i])) {
84             return ((chan - freq_cvt[i].cmin) * FREQ_STEP) + freq_cvt[i].fmin;
85         }
86     }
87     return 0;
88 }
89
90 /*
91  * Get channel representation string given a Frequency
92  */
93 gchar*
94 ieee80211_mhz_to_str(guint freq){
95     gint chan = ieee80211_mhz_to_chan(freq);
96     gboolean is_bg = FREQ_IS_BG(freq);
97
98     if (chan < 0) {
99         return g_strdup_printf("%u", freq);
100     } else {
101         return g_strdup_printf("%u [%s %u]", freq, is_bg ? "BG" : "A",
102             chan);
103     }
104 }
105
106 /*
107  * Editor modelines
108  *
109  * Local Variables:
110  * c-basic-offset: 4
111  * tab-width: 8
112  * indent-tabs-mode: nil
113  * End:
114  *
115  * ex: set shiftwidth=4 tabstop=8 expandtab:
116  * :indentSize=4:tabSize=8:noTabs=true:
117  */