aboutsummaryrefslogtreecommitdiff
path: root/dataservices/datatop/src/datatop_dev_poll.c
diff options
context:
space:
mode:
authorLuca Stefani <luca020400@lineageos.org>2017-08-24 22:24:29 +0200
committerdd3boh <dade.garberi@gmail.com>2017-09-17 14:13:47 +0200
commit66c36e2cb752b01a8c7fbe45e32ccc1681fb9d4b (patch)
treeabb6d0f255601442e21e1caea3ccb5c6a7b077d4 /dataservices/datatop/src/datatop_dev_poll.c
parent7d3687801d2c4b503807698e34a5a3dd881bfce4 (diff)
msm8996-common: Import marlin dataservices
Change-Id: I9d2e47585ac93bbdf28e275e9ec0c669b9f8be3e Signed-off-by: Marco Zanin (B--B) <mrczn.bb@gmail.com>
Diffstat (limited to 'dataservices/datatop/src/datatop_dev_poll.c')
-rw-r--r--dataservices/datatop/src/datatop_dev_poll.c320
1 files changed, 320 insertions, 0 deletions
diff --git a/dataservices/datatop/src/datatop_dev_poll.c b/dataservices/datatop/src/datatop_dev_poll.c
new file mode 100644
index 0000000..0dcab1e
--- /dev/null
+++ b/dataservices/datatop/src/datatop_dev_poll.c
@@ -0,0 +1,320 @@
+/************************************************************************
+Copyright (c) 2015, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of The Linux Foundation nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+************************************************************************/
+
+/**
+ * @file datatop_dev_poll.c
+ * @brief Adds ability for data collection from /proc/net/dev
+ *
+ * File contains methods for searching and polling data from
+ * "/proc/net/dev"
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "datatop_interface.h"
+#include "datatop_fileops.h"
+#include "datatop_str.h"
+
+#define DTOP_DEV_SIZE 8192
+#define DTOP_DEV_LINE (DTOP_DEV_SIZE>>2)
+
+/**
+* @struct dtop_dev_vars
+* @brief Struct used to hold necessary variables for /proc/net/dev dpg
+*
+* @var dtop_dev_vars::line
+* Array of strings where necessary dp names and values are held.
+* @var dtop_dev_vars::line_count
+* Number of lines the file is that the dpg represents.
+*/
+struct dtop_dev_vars {
+ char **line;
+ int line_count;
+};
+
+/**
+ * @brief Parses lines with data in "/proc/net/dev"
+ *
+ * @param line1 Line to parse to find datapoint names and values.
+ * @param len1 Length of line1.
+ * @param index Index in the dictionary the key (name) is added to.
+ * @param dict Dictionary the keys and values are added to.
+ */
+static void dt_dev_parse(char *line1, int len1,
+ int index, struct dt_procdict *dict)
+{
+ int i, start = 0;
+ int j, k, n;
+ i = 0;
+ while (line1[i] == ' ' || line1[i] == ' ')
+ i++;
+ dict->key[index] = &line1[i];
+ for (i = 0; i < len1; i++) {
+ if (line1[i] == ':') {
+ line1[i+1] = 0;
+ start = i+2;
+ break;
+ }
+ }
+
+ k = 0;
+ for (j = start; j < len1; j++) {
+ if (line1[j] != ' ' && line1[j] != ' ') {
+ dict->val[k] = &line1[j];
+ n = j;
+ while (line1[n] != ' ' && line1[n] != ' ')
+ n++;
+ if (n < len1)
+ line1[n] = 0;
+ j = n;
+ k++;
+ }
+ }
+}
+
+/**
+ * @brief Stores the data collected from "/proc/net/dev"
+ *
+ * @param dpg Struct that polled data is added to.
+ * @return DTOP_POLL_IO_ERR - Poll of dpg unsuccessful.
+ * @return DTOP_POLL_OK - Poll of dpg successful.
+ */
+int dtop_dev_poll(struct dtop_data_point_gatherer *dpg)
+{
+ char *data;
+ int *line_len = malloc(sizeof(int) *
+ ((struct dtop_dev_vars *)
+ (dpg->priv))->line_count);
+ int read;
+ struct dt_procdict *dict = malloc(sizeof(struct dt_procdict)
+ *((struct dtop_dev_vars *)
+ (dpg->priv))->line_count-2);
+ int j, n, sum;
+ int index = 0;
+ int dp = 0;
+
+ read = dt_read_file(dpg->file, &data, DTOP_DEV_SIZE);
+ if (read == 0 || data == 0)
+ return DTOP_POLL_IO_ERR;
+
+ sum = 0;
+ /* Assigns each line read from the file, a length */
+ for (n = 0; n < ((struct dtop_dev_vars *)
+ (dpg->priv))->line_count; n++) {
+ line_len[n] = dt_read_line(((struct dtop_dev_vars *)
+ (dpg->priv))->line[n],
+ DTOP_DEV_LINE, data,
+ DTOP_DEV_SIZE, sum);
+ if (n <= (((struct dtop_dev_vars *)
+ (dpg->priv))->line_count - 1)) {
+ sum += (line_len[n] + 1);
+ }
+
+ }
+
+ for (n = 2; n < ((struct dtop_dev_vars *)
+ (dpg->priv))->line_count; n++) {
+ dt_dev_parse(((struct dtop_dev_vars *)
+ (dpg->priv))->line[n], line_len[n],
+ index, &dict[index]);
+ index++;
+ }
+
+
+ /* Assigns the dp value to the dp struct */
+ for (n = 2; n < ((struct dtop_dev_vars *)
+ (dpg->priv))->line_count; n++) {
+ for (j = 0; j < 16; j++) {
+ dtop_store_dp(&(dpg->data_points[dp]),
+ dict[n-2].val[j]);
+ dp++;
+ }
+ }
+
+ dt_free(&data);
+ free(line_len);
+ free(dict);
+ return DTOP_POLL_OK;
+}
+
+/**
+ * @brief Frees dynamically allocated "/proc/net/dev" dpg.
+ *
+ * Frees the memory of the dpg along with it's data_points
+ * and other malloc'd memory no longer needed.
+ *
+ * @param dpg Dpg to deconstruct and deallocate memory for.
+ */
+static void dtop_dev_dpg_deconstructor
+ (struct dtop_data_point_gatherer *dpset)
+{
+ int i, j, dp;
+ dp = 0;
+ for (j = 0; j < ((((struct dtop_dev_vars *)
+ (dpset->priv))->line_count)-2); j++) {
+ for (i = 0; i < 16; i++) {
+ free(dpset->data_points[dp].prefix);
+ dp++;
+ }
+ }
+ free(dpset->data_points);
+ for (i = 0; i < ((struct dtop_dev_vars *)
+ (dpset->priv))->line_count; i++)
+ free(((struct dtop_dev_vars *)(dpset->priv))->line[i]);
+ free(((struct dtop_dev_vars *)(dpset->priv))->line);
+ free(((struct dtop_dev_vars *)(dpset->priv)));
+ free(dpset);
+}
+
+/**
+ * @brief Creates a dpg for "/proc/net/dev" file
+ *
+ * Dynamically allocates memory for dpg which is then added to a linked list
+ * via the dtop_register(dpg) function call.
+ *
+ * @param data_points dtop_data_point struct that dpg points to.
+ * @param storage dtop_dev_vars struct that holds relevant dpg variables.
+ */
+static void construct_dev_file_dpg(struct dtop_dev_vars *storage,
+ int dp_count, struct dtop_data_point *data_points)
+{
+ struct dtop_data_point_gatherer *dpg = malloc
+ (sizeof(struct dtop_data_point_gatherer));
+
+ dpg->prefix = "/proc/net/dev";
+ dpg->file = "/proc/net/dev";
+ dpg->poll = dtop_dev_poll;
+ dpg->data_points = data_points;
+ dpg->priv = (struct dtop_dev_vars *)storage;
+ dpg->data_points_len = dp_count;
+ dpg->deconstruct = dtop_dev_dpg_deconstructor;
+
+ dtop_register(dpg);
+}
+
+/**
+ * @brief Scans "/proc/net/dev in order to autodetect dps.
+ *
+ * Searches through "/proc/net/dev" file for all available data
+ * points to create as dp structs.
+ *
+ * @param name This is the file name "/proc/net/dev" passed in by dtop_dev_init
+ * @param storage dtop_dev_vars struct where relevant variables are stored.
+ */
+int dtop_dev_search(char *name, struct dtop_dev_vars *storage)
+{
+ int i, n, sum;
+ char *data;
+ int *line_len = malloc(sizeof(int) * storage->line_count);
+ int read;
+ struct dt_procdict dict;
+ struct dt_procdict dev_dict;
+ struct dtop_data_point *data_points = malloc
+ (sizeof(struct dtop_data_point) * 16 * (storage->line_count-2));
+ int dp_count = (16 * (storage->line_count - 2));
+ int index = 0;
+ int dp = 0;
+
+ storage->line = malloc(storage->line_count * sizeof(*storage->line));
+
+ for (i = 0; i < storage->line_count; i++)
+ storage->line[i] = malloc(sizeof(char) * DTOP_DEV_LINE);
+
+ dev_dict.val[0] = "bytes";
+ dev_dict.val[1] = "packets";
+ dev_dict.val[2] = "errs";
+ dev_dict.val[3] = "drop";
+ dev_dict.val[4] = "fifo";
+ dev_dict.val[5] = "frame";
+ dev_dict.val[6] = "compressed";
+ dev_dict.val[7] = "multicast";
+ dev_dict.val[8] = "bytes";
+ dev_dict.val[9] = "packets";
+ dev_dict.val[10] = "errs";
+ dev_dict.val[11] = "drop";
+ dev_dict.val[12] = "fifo";
+ dev_dict.val[13] = "colls";
+ dev_dict.val[14] = "carrier";
+ dev_dict.val[15] = "compressed";
+
+ read = dt_read_file(name, &data, DTOP_DEV_SIZE);
+ if (read == 0 || data == 0)
+ return DTOP_POLL_IO_ERR;
+
+ sum = 0;
+ /* Assigns each line read from the file, a length */
+ for (n = 0; n < storage->line_count; n++) {
+ line_len[n] = dt_read_line(storage->line[n],
+ DTOP_DEV_LINE, data,
+ DTOP_DEV_SIZE, sum);
+ if (n < (storage->line_count - 1))
+ sum += (line_len[n] + 1);
+ }
+
+ construct_dev_file_dpg(storage, dp_count, data_points);
+
+ for (n = 2; n < storage->line_count; n++) {
+ dt_dev_parse(storage->line[n], line_len[n], index, &dict);
+ index++;
+ }
+
+ for (n = 2; n < storage->line_count; n++) {
+ for (i = 0; i < 16; i++) {
+ char *pref = malloc(30 * sizeof(char));
+ data_points[dp].skip = 0;
+ data_points[dp].initial_data_populated = NOT_POPULATED;
+ if (i < 8)
+ strlcpy(pref, "Receive:", 30 * sizeof(char));
+ else if (i >= 8)
+ strlcpy(pref, "Transmit:", 30 * sizeof(char));
+ strlcat(pref, dev_dict.val[i], 30 * sizeof(char));
+ data_points[dp].prefix = pref;
+ data_points[dp].name = dict.key[n-2];
+ data_points[dp].type = DTOP_ULONG;
+ dp++;
+ }
+ index++;
+ }
+
+ free(line_len);
+ dt_free(&data);
+ return DTOP_POLL_OK;
+}
+
+/**
+ * @brief Calls dtop_search for "/proc/net/dev" file.
+ */
+void dtop_dev_init(void)
+{
+ struct dtop_dev_vars *storage = malloc
+ (sizeof(struct dtop_dev_vars));
+ storage->line_count = dtop_get_file_line_amount("/proc/net/dev");
+ dtop_dev_search("/proc/net/dev", storage);
+}