1/*
2 * Copyright 2006-2015, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Axel D��rfler, axeld@pinc-software.de
7 *		Oliver Tappe, zooey@hirschkaefer.de
8 *		Atis Elsts, the.kfx@gmail.com
9 */
10
11
12#include "MediaTypes.h"
13
14#include <stdint.h>
15#include <string.h>
16
17extern "C" {
18#	include <freebsd_network/compat/net/if_media.h>
19}
20
21
22struct media_type {
23	int			type;
24	const char*	name;
25	const char* pretty;
26	int 		subtype_mask;
27	struct {
28		int subtype;
29		const char* name;
30		const char* pretty;
31	} subtypes [10];
32	struct {
33		int option;
34		bool read_only;
35		const char* name;
36		const char* pretty;
37	} options [6];
38};
39
40
41const media_type kMediaTypes[] = {
42	{
43		IFM_ETHER,
44		"ether",
45		"Ethernet",
46		IFM_TMASK,
47		{
48			//{ IFM_AUTO, "auto", "Auto-select" },
49			//{ IFM_AUI, "AUI", "10 MBit, AUI" },
50			//{ IFM_10_2, "10base2", "10 MBit, 10BASE-2" },
51			{ IFM_10_T, "10baseT", "10 MBit, 10BASE-T" },
52			{ IFM_100_TX, "100baseTX", "100 MBit, 100BASE-TX" },
53			{ IFM_1000_T, "1000baseT", "1 GBit, 1000BASE-T" },
54			{ IFM_1000_SX, "1000baseSX", "1 GBit, 1000BASE-SX" },
55			{ IFM_10G_T, "10GbaseT", "10 GBit, 10GBASE-T" },
56			{ IFM_10G_SR, "10GbaseSR", "10 Gbit, 850 nm Fibre"},
57			{ IFM_10G_LR, "10GbaseLR", "10 Gbit, 1310 nm Fibre"},
58			{ IFM_10G_LRM, "10GbaseLRM", "10 Gbit, 1300 nm Fibre"},
59			{ IFM_10G_TWINAX, "10GbaseCR", "10 Gbit, Direct Attach"},
60			{ -1, NULL, NULL }
61		},
62		{
63			{ -1, false, NULL, NULL }
64		}
65	},
66	{
67		IFM_IEEE80211,
68		"80211",
69		"Wireless Ethernet",
70		IFM_MMASK,
71		{
72			{ IFM_IEEE80211_11A, "802.11a", "802.11a" },
73			{ IFM_IEEE80211_11B, "802.11b", "802.11b" },
74			{ IFM_IEEE80211_11G, "802.11g", "802.11g" },
75			{ IFM_IEEE80211_FH, "802.11 FH", "802.11 FH" },
76			{ IFM_IEEE80211_11NA, "802.11n(a)", "802.11n(a)" },
77			{ IFM_IEEE80211_11NG, "802.11n(g)", "802.11n(g)" },
78			{ IFM_IEEE80211_VHT5G, "802.11ac", "802.11ac" },
79			{ -1, NULL, NULL }
80		},
81		{
82			{ -1, false, NULL, NULL }
83		}
84	},
85	{
86		0, // for generic options
87		"all",
88		"All",
89		IFM_TMASK,
90		{
91			{ IFM_AUTO, "auto", "Auto-select" },
92			{ -1, NULL, NULL }
93		},
94		{
95			{ IFM_FDX, true, "fullduplex", "Full Duplex" },
96			{ IFM_HDX, true, "halfduplex", "Half Duplex" },
97			{ IFM_LOOP, true, "loop", "Loop" },
98			//{ IFM_ACTIVE, false, "active", "Active" },
99			{ -1, false, NULL, NULL }
100		}
101	},
102	{ -1, NULL, NULL, -1, {{ -1, NULL, NULL }}, {{ -1, false, NULL, NULL }} }
103};
104
105
106const char*
107get_media_type_name(size_t index)
108{
109	if (index < sizeof(kMediaTypes) / sizeof(kMediaTypes[0]))
110		return kMediaTypes[index].pretty;
111
112	return NULL;
113}
114
115
116const char*
117get_media_subtype_name(size_t typeIndex, size_t subIndex)
118{
119	if (typeIndex < sizeof(kMediaTypes) / sizeof(kMediaTypes[0])) {
120		if (kMediaTypes[typeIndex].subtypes[subIndex].subtype >= 0)
121			return kMediaTypes[typeIndex].subtypes[subIndex].name;
122	}
123
124	return NULL;
125}
126
127
128bool
129media_parse_subtype(const char* string, int media, int* type)
130{
131	for (size_t i = 0; kMediaTypes[i].type >= 0; i++) {
132		// only check for generic or correct subtypes
133		if (kMediaTypes[i].type &&
134			kMediaTypes[i].type != media)
135			continue;
136		for (size_t j = 0; kMediaTypes[i].subtypes[j].subtype >= 0; j++) {
137			if (strcmp(kMediaTypes[i].subtypes[j].name, string) == 0) {
138				// found a match
139				*type = kMediaTypes[i].subtypes[j].subtype;
140				return true;
141			}
142		}
143	}
144	return false;
145}
146
147
148const char*
149media_type_to_string(int media)
150{
151	for (size_t i = 0; kMediaTypes[i].type >= 0; i++) {
152		// loopback doesn't really have a media anyway
153		if (IFM_TYPE(media) == 0)
154			break;
155
156		// only check for generic or correct subtypes
157		if (kMediaTypes[i].type
158			&& kMediaTypes[i].type != IFM_TYPE(media))
159			continue;
160
161		const int subtype = (media & kMediaTypes[i].subtype_mask);
162		for (size_t j = 0; kMediaTypes[i].subtypes[j].subtype >= 0; j++) {
163			if (kMediaTypes[i].subtypes[j].subtype == subtype) {
164				// found a match
165				return kMediaTypes[i].subtypes[j].pretty;
166			}
167		}
168	}
169
170	return NULL;
171}
172