~cairo-dock-team/cairo-dock-plug-ins/plug-ins

« back to all changes in this revision

Viewing changes to netspeed/src/applet-netspeed.c

  • Committer: Matthieu Baerts
  • Date: 2014-10-19 00:26:10 UTC
  • Revision ID: matttbe@gmail.com-20141019002610-ulf26s9b4c4rw10r
We just switched from BZR to Git.
Follow us on Github: https://github.com/Cairo-Dock

Note: we will only use Github to manage our source code and all pull requests.
Please continue to report your bugs/ideas/messages on our forum or Launchpad! 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
* This file is a part of the Cairo-Dock project
3
 
*
4
 
* Copyright : (C) see the 'copyright' file.
5
 
* E-mail    : see the 'copyright' file.
6
 
*
7
 
* This program is free software; you can redistribute it and/or
8
 
* modify it under the terms of the GNU General Public License
9
 
* as published by the Free Software Foundation; either version 3
10
 
* of the License, or (at your option) any later version.
11
 
*
12
 
* This program is distributed in the hope that it will be useful,
13
 
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
* GNU General Public License for more details.
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
 
#include <stdlib.h>
21
 
#include <stdio.h>
22
 
#include <string.h>
23
 
 
24
 
#ifdef __FreeBSD__ 
25
 
#include <sys/types.h>
26
 
#include <sys/socket.h>
27
 
#include <ifaddrs.h>
28
 
#include <net/if.h>
29
 
#include <net/if_types.h>
30
 
#include <net/if_dl.h> 
31
 
#endif
32
 
 
33
 
#include "applet-struct.h"
34
 
#include "applet-notifications.h"
35
 
#include "applet-netspeed.h"
36
 
#include "cairo-dock.h"
37
 
 
38
 
#define NETSPEED_DATA_PIPE "/proc/net/dev"
39
 
 
40
 
 
41
 
// Prend un debit en octet par seconde et le transforme en une chaine de la forme : xxx yB/s
42
 
static void cd_netspeed_formatRate (unsigned long long rate, gchar* debit, int iBufferSize, gboolean bLong)
43
 
{
44
 
        int smallRate;
45
 
        if (rate <= 0)
46
 
        {
47
 
                if (bLong)
48
 
                        snprintf (debit, iBufferSize, "0 %s/s", D_("B"));
49
 
                else
50
 
                        snprintf (debit, iBufferSize, "0");
51
 
        }
52
 
        else if (rate < 1024)
53
 
        {
54
 
                smallRate = rate;
55
 
                if (bLong)
56
 
                        snprintf (debit, iBufferSize, "%i %s/s", smallRate, D_("B"));
57
 
                else
58
 
                        snprintf (debit, iBufferSize, "%iB", smallRate);
59
 
        }
60
 
        else if (rate < (1<<20))
61
 
        {
62
 
                smallRate = rate >> 10;
63
 
                if (bLong)
64
 
                        snprintf (debit, iBufferSize, "%i %s/s", smallRate, D_("KB"));
65
 
                else
66
 
                        snprintf (debit, iBufferSize, "%iK", smallRate);
67
 
        }
68
 
        else if (rate < (1<<30))
69
 
        {
70
 
                smallRate = rate >> 20;
71
 
                if (bLong)
72
 
                        snprintf (debit, iBufferSize, "%i %s/s", smallRate, D_("MB"));
73
 
                else
74
 
                        snprintf (debit, iBufferSize, "%iM", smallRate);
75
 
        }
76
 
        else if (rate < ((unsigned long long)1<<40))
77
 
        {
78
 
                smallRate = rate >> 30;
79
 
                if (bLong)
80
 
                        snprintf (debit, iBufferSize, "%i %s/s", smallRate, D_("GB"));
81
 
                else
82
 
                        snprintf (debit, iBufferSize, "%iG", smallRate);
83
 
        }
84
 
        else  // c'est vraiment pour dire qu'on est exhaustif :-)
85
 
        {
86
 
                smallRate = rate >> 40;
87
 
                if (bLong)
88
 
                        snprintf (debit, iBufferSize, "%i %s/s", smallRate, D_("TB"));
89
 
                else
90
 
                        snprintf (debit, iBufferSize, "%iT", smallRate);
91
 
        }
92
 
}
93
 
 
94
 
 
95
 
void cd_netspeed_format_value (CairoDataRenderer *pRenderer, int iNumValue, gchar *cFormatBuffer, int iBufferLength, GldiModuleInstance *myApplet)
96
 
{
97
 
        static gchar s_upRateFormatted[11];
98
 
        cd_netspeed_formatRate (iNumValue == 0 ? myData.iDownloadSpeed : myData.iUploadSpeed, s_upRateFormatted, 11, FALSE);
99
 
        snprintf (cFormatBuffer, iBufferLength,
100
 
                "%s%s",
101
 
                cairo_data_renderer_can_write_values (pRenderer) ? (iNumValue == 0 ?"↓" : "↑") : "",
102
 
                s_upRateFormatted);
103
 
}
104
 
 
105
 
 
106
 
void cd_netspeed_get_data (GldiModuleInstance *myApplet)
107
 
{
108
 
        g_timer_stop (myData.pClock);
109
 
        double fTimeElapsed = g_timer_elapsed (myData.pClock, NULL);
110
 
        g_timer_start (myData.pClock);
111
 
        g_return_if_fail (fTimeElapsed > 0.1 || !myData.bInitialized);
112
 
        myData.bAcquisitionOK = FALSE;
113
 
        
114
 
        #ifdef __FreeBSD__  // thanks to Max Power for the BSD port
115
 
        struct ifaddrs *ifap, *ifa;
116
 
        if (getifaddrs(&ifap) != 0)
117
 
        {
118
 
                cd_warning ("NetSpeed : getifaddrs");
119
 
                return;
120
 
        }
121
 
        long long int iReceivedBytes = 0, iTransmittedBytes = 0;
122
 
        for (ifa = ifap; ifa; ifa = ifa->ifa_next)  // for all interfaces
123
 
        {
124
 
                // check the interface
125
 
                struct sockaddr_dl *sdl = (struct sockaddr_dl *) ifa->ifa_addr;
126
 
                if (sdl->sdl_type != IFT_ETHER)
127
 
                        continue;  // skip all non ethernet interfaces such as loopback, usb, etc...
128
 
                if (myConfig.cInterface != NULL && strcmp (ifa->ifa_name, myConfig.cInterface) != 0)  // we monitor a given interface
129
 
                        continue;
130
 
                
131
 
                myData.bAcquisitionOK = TRUE;
132
 
                struct if_data *data = (struct if_data*) ifa->ifa_data;  // get data
133
 
                if (data != NULL)
134
 
                {
135
 
                        iReceivedBytes += (long long int)data->ifi_ibytes;
136
 
                        iTransmittedBytes += (long long int)data->ifi_obytes;
137
 
                }
138
 
        }
139
 
        #else
140
 
        gchar *cContent = NULL;
141
 
        gsize length=0;
142
 
        GError *erreur = NULL;
143
 
        g_file_get_contents (NETSPEED_DATA_PIPE, &cContent, &length, &erreur);
144
 
        if (erreur != NULL)
145
 
        {
146
 
                cd_warning("NetSpeed : %s", erreur->message);
147
 
                g_error_free(erreur);
148
 
                return;
149
 
        }
150
 
        int iNumLine = 1;
151
 
        gchar *tmp = cContent, *if_data;
152
 
        long long int iReceivedBytes = 0, iTransmittedBytes = 0;
153
 
        do
154
 
        {
155
 
                if (iNumLine > 2)  // first 2 lines are the names of the fields (next lines are the various interfaces, in any order, the loopback is not always the first one).
156
 
                {
157
 
                        while (*tmp == ' ')  // drop spaces
158
 
                                tmp ++;
159
 
                        
160
 
                        // "interface : data"
161
 
                        if_data = strchr (tmp, ':');
162
 
                        if (!if_data)  // shouldn't occur
163
 
                                break;
164
 
                        *if_data = '\0';
165
 
                        
166
 
                        if ((myConfig.cInterface == NULL && strcmp (tmp, "lo") != 0)  // we monitor all interfaces except 'lo'
167
 
                        || (myConfig.cInterface != NULL && strcmp (tmp, myConfig.cInterface) == 0))  // we monitor a given interface
168
 
                        {
169
 
                                myData.bAcquisitionOK = TRUE;
170
 
                                tmp = if_data + 1;  // drop ':'
171
 
                                while (*tmp == ' ')  // drop spaces
172
 
                                        tmp ++;
173
 
                                iReceivedBytes += atoll (tmp);
174
 
                                
175
 
                                int i = 0;
176
 
                                for (i = 0; i < 8; i ++)  // drop 8 next values
177
 
                                {
178
 
                                        while (*tmp != ' ')  // drop numbers
179
 
                                                tmp ++;
180
 
                                        while (*tmp == ' ')  // drop spaces
181
 
                                                tmp ++;
182
 
                                }
183
 
                                iTransmittedBytes += atoll (tmp);
184
 
 
185
 
                                if (myConfig.cInterface != NULL) // only one interface
186
 
                                        break ;
187
 
                        }
188
 
                        else  // skip this interface
189
 
                        {
190
 
                                tmp = if_data + 1;  // drop ':'
191
 
                        }
192
 
                }
193
 
                tmp = strchr (tmp, '\n');
194
 
                if (tmp == NULL || *(++tmp) == '\0') // EOF
195
 
                        break;
196
 
                iNumLine ++;
197
 
        }
198
 
        while (1);
199
 
        g_free (cContent);
200
 
        #endif
201
 
        if (myData.bInitialized)  // we already have some previous values => we can compute the speed
202
 
        {
203
 
                myData.iDownloadSpeed = (iReceivedBytes - myData.iReceivedBytes) / fTimeElapsed;
204
 
                myData.iUploadSpeed = (iTransmittedBytes - myData.iTransmittedBytes) / fTimeElapsed;
205
 
        }
206
 
        myData.iReceivedBytes = iReceivedBytes;
207
 
        myData.iTransmittedBytes = iTransmittedBytes;
208
 
 
209
 
        if (! myData.bInitialized)
210
 
                myData.bInitialized = TRUE;
211
 
}
212
 
 
213
 
gboolean cd_netspeed_update_from_data (GldiModuleInstance *myApplet)
214
 
{
215
 
        static double s_fValues[CD_NETSPEED_NB_MAX_VALUES];
216
 
        static gchar s_upRateFormatted[11];
217
 
        static gchar s_downRateFormatted[11];
218
 
        CD_APPLET_ENTER;
219
 
        if ( ! myData.bAcquisitionOK)
220
 
        {
221
 
                if (myConfig.iInfoDisplay == CAIRO_DOCK_INFO_ON_LABEL)
222
 
                {
223
 
                        if (myConfig.defaultTitle) // has another default name
224
 
                                CD_APPLET_SET_NAME_FOR_MY_ICON (myConfig.defaultTitle);
225
 
                        else
226
 
                                CD_APPLET_SET_NAME_FOR_MY_ICON (myApplet->pModule->pVisitCard->cTitle);
227
 
                }
228
 
                else if (myConfig.iInfoDisplay == CAIRO_DOCK_INFO_ON_ICON)
229
 
                        CD_APPLET_SET_QUICK_INFO_ON_MY_ICON ("N/A");
230
 
                
231
 
                memset (s_fValues, 0, sizeof (s_fValues));
232
 
                CD_APPLET_RENDER_NEW_DATA_ON_MY_ICON (s_fValues);
233
 
                
234
 
                gldi_task_downgrade_frequency (myData.pPeriodicTask);
235
 
        }
236
 
        else
237
 
        {
238
 
                gldi_task_set_normal_frequency (myData.pPeriodicTask);
239
 
                
240
 
                if (! myData.bInitialized)
241
 
                {
242
 
                        if (myConfig.iInfoDisplay == CAIRO_DOCK_INFO_ON_ICON)
243
 
                                CD_APPLET_SET_QUICK_INFO_ON_MY_ICON (myDock ? "..." : D_("Loading"));
244
 
                        memset (s_fValues, 0, sizeof (s_fValues));
245
 
                        CD_APPLET_RENDER_NEW_DATA_ON_MY_ICON (s_fValues);
246
 
                }
247
 
                else
248
 
                {
249
 
                        if (myConfig.iInfoDisplay == CAIRO_DOCK_INFO_ON_LABEL)
250
 
                        {
251
 
                                cd_netspeed_formatRate (myData.iUploadSpeed, s_upRateFormatted, 11, myDesklet != NULL);
252
 
                                cd_netspeed_formatRate (myData.iDownloadSpeed, s_downRateFormatted, 11, myDesklet != NULL);
253
 
                                CD_APPLET_SET_NAME_FOR_MY_ICON_PRINTF ("↓%s - ↑%s", s_downRateFormatted, s_upRateFormatted);
254
 
                        }
255
 
                        
256
 
                        if(myData.iUploadSpeed > myData.iMaxUpRate) {
257
 
                                myData.iMaxUpRate = myData.iUploadSpeed;
258
 
                        }
259
 
                        if(myData.iDownloadSpeed > myData.iMaxDownRate) {
260
 
                                myData.iMaxDownRate = myData.iDownloadSpeed;
261
 
                        }
262
 
                        
263
 
                        double fUpValue, fDownValue;
264
 
                        if (myData.iMaxUpRate != 0)
265
 
                                fUpValue = (double) myData.iUploadSpeed / myData.iMaxUpRate;
266
 
                        else
267
 
                                fUpValue = 0.;
268
 
                        if (myData.iMaxDownRate != 0)
269
 
                                fDownValue = (double) myData.iDownloadSpeed / myData.iMaxDownRate;
270
 
                        else
271
 
                                fDownValue = 0.;
272
 
                        
273
 
                        s_fValues[0] = fDownValue;
274
 
                        s_fValues[1] = fUpValue;
275
 
                        CD_APPLET_RENDER_NEW_DATA_ON_MY_ICON (s_fValues);
276
 
                }
277
 
        }
278
 
        CD_APPLET_LEAVE (TRUE);
279
 
}