]> git.ipfire.org Git - network.git/blob - src/libnetwork/phy.c
9e364dec4a5d05488781ffe85e06cde182c15673
[network.git] / src / libnetwork / phy.c
1 /*#############################################################################
2 # #
3 # IPFire.org - A linux based firewall #
4 # Copyright (C) 2018 IPFire Network Development Team #
5 # #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
10 # #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
15 # #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
18 # #
19 #############################################################################*/
20
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24
25 #include <network/libnetwork.h>
26 #include <network/logging.h>
27 #include "libnetwork-private.h"
28
29 struct network_phy {
30 struct network_ctx* ctx;
31 int refcount;
32
33 int index;
34 char* name;
35 };
36
37 static int phy_get_index(const char* name) {
38 char path[1024];
39 char index[8];
40
41 snprintf(path, sizeof(path), "/sys/class/ieee80211/%s/index", name);
42
43 FILE* f = fopen(path, "r");
44 if (!f)
45 return -1;
46
47 int p = fread(index, 1, sizeof(index), f);
48 if (p < 0) {
49 fclose(f);
50 return -1;
51 }
52
53 // Terminate buffer
54 index[p] = '\0';
55 fclose(f);
56
57 return atoi(index);
58 }
59
60 NETWORK_EXPORT int network_phy_new(struct network_ctx* ctx, struct network_phy** phy,
61 const char* name) {
62 if (!name)
63 return -EINVAL;
64
65 int index = phy_get_index(name);
66 if (index < 0)
67 return -ENODEV;
68
69 struct network_phy* p = calloc(1, sizeof(*p));
70 if (!p)
71 return -ENOMEM;
72
73 // Initalise object
74 p->ctx = network_ref(ctx);
75 p->refcount = 1;
76
77 DEBUG(p->ctx, "Allocated phy at %p\n", p);
78 *phy = p;
79 return 0;
80 }
81
82 NETWORK_EXPORT struct network_phy* network_phy_ref(struct network_phy* phy) {
83 if (!phy)
84 return NULL;
85
86 phy->refcount++;
87 return phy;
88 }
89
90 static void network_phy_free(struct network_phy* phy) {
91 DEBUG(phy->ctx, "Releasing phy at %p\n", phy);
92
93 if (phy->name)
94 free(phy->name);
95
96 network_unref(phy->ctx);
97 free(phy);
98 }
99
100 NETWORK_EXPORT struct network_phy* network_phy_unref(struct network_phy* phy) {
101 if (!phy)
102 return NULL;
103
104 if (--phy->refcount > 0)
105 return phy;
106
107 network_phy_free(phy);
108 return NULL;
109 }