summaryrefslogtreecommitdiff
path: root/cleopatre/application/managerd/src/vs_mme.c
diff options
context:
space:
mode:
Diffstat (limited to 'cleopatre/application/managerd/src/vs_mme.c')
-rw-r--r--cleopatre/application/managerd/src/vs_mme.c115
1 files changed, 105 insertions, 10 deletions
diff --git a/cleopatre/application/managerd/src/vs_mme.c b/cleopatre/application/managerd/src/vs_mme.c
index b9afe32948..76e38345c1 100644
--- a/cleopatre/application/managerd/src/vs_mme.c
+++ b/cleopatre/application/managerd/src/vs_mme.c
@@ -21,12 +21,24 @@
#include <stdio.h>
#include <string.h>
+#include <syslog.h>
#include "bridge.h"
#include "vs_mme.h"
#define FIRMWARE_LABEL "irmware"
+static void _prepare_confirm (struct managerd_ctx *ctx, MME_t *request, MME_t *confirm, int len)
+{
+ memset (confirm, '\0', len);
+ memcpy (confirm->mme_dest, request->mme_src, ETH_ALEN);
+ memcpy (confirm->mme_src, ctx->br_mac_addr, ETH_ALEN);
+ confirm->mtype = request->mtype;
+ confirm->mmv = request->mmv;
+ confirm->mmtype = (request->mmtype & ~MME_TYPE_MASK) | MME_TYPE_CNF;
+ confirm->fmi = 0;
+}
+
/**
* Send a VS_GET_VERSION MME to BR interface.
*
@@ -54,18 +66,12 @@ enum bridge_status vs_mme_get_version (struct managerd_ctx *ctx, MME_t *request,
if(memcmp ((char *)request + sizeof(MME_t), OUI_SPIDCOM, 3))
return TO_DROP;
- /* prepare ethernet header */
- memset (confirm, '\0', len);
- memcpy (confirm->mme_dest, request->mme_src, ETH_ALEN);
- memcpy (confirm->mme_src, ctx->br_mac_addr, ETH_ALEN);
- confirm->mtype = request->mtype;
- confirm->mmv = request->mmv;
- confirm->mmtype = MME_TYPE_VS_GET_VERSION | MME_TYPE_CNF;
- confirm->fmi = 0;
+ get_version_cnf = (vs_get_version_cnf_t *)((unsigned char*)confirm + sizeof(MME_t));
+
+ /* prepare confirm packet */
+ _prepare_confirm (ctx, request, confirm, len);
/* set get_version inside confirm buffer */
- get_version_cnf = (vs_get_version_cnf_t *)((unsigned char*)confirm + sizeof(MME_t));
- /* fill get_version */
memcpy (get_version_cnf->oui, OUI_SPIDCOM, 3);
get_version_cnf->result = 0;
get_version_cnf->device_id = SPC300_ID;
@@ -102,3 +108,92 @@ enum bridge_status vs_mme_get_version (struct managerd_ctx *ctx, MME_t *request,
bridge_send_to_br (ctx, (uint8_t *)confirm, sizeof(MME_t) + sizeof(vs_get_version_cnf_t));
return TO_DROP;
}
+
+/**
+ * Send a VS_ETH_STATS MME to BR interface.
+ *
+ * \param ctx managerd context.
+ * \param request MME containg VS_ETH_STATS request.
+ * \param confirm MME buffer to put VS_ETH_STATS confirm.
+ * \param len confirm buffer length.
+ * \return error code.
+ */
+enum bridge_status vs_mme_eth_stats (struct managerd_ctx *ctx, MME_t *request, MME_t *confirm, int len)
+{
+ vs_eth_stats_req_t *eth_stats_req;
+ vs_eth_stats_cnf_t *eth_stats_cnf;
+
+ FILE *fp;
+ char tmp_buffer[256];
+ char name[64], *ptr;
+ unsigned long long rx_bytes, rx_packets, tx_bytes, tx_packets;
+
+ assert (NULL != ctx);
+ assert (NULL != request);
+ assert (NULL != confirm);
+ assert (len >= sizeof(vs_eth_stats_cnf_t) + sizeof(MME_t));
+
+ eth_stats_req = (vs_eth_stats_req_t *)((unsigned char*)request + sizeof(MME_t));
+ eth_stats_cnf = (vs_eth_stats_cnf_t *)((unsigned char*)confirm + sizeof(MME_t));
+
+ if(memcmp (eth_stats_req->oui, OUI_SPIDCOM, 3))
+ return TO_DROP;
+
+ /* prepare confirm packet */
+ _prepare_confirm (ctx, request, confirm, len);
+ memcpy (eth_stats_cnf->oui, OUI_SPIDCOM, 3);
+ eth_stats_cnf->result = MME_RESULT_FAILURE;
+
+ /* check request type */
+ if(ETH_STATS_COMMAND_GET == eth_stats_req->command)
+ {
+ if((fp = fopen ("/proc/net/dev", "r")) == NULL)
+ goto failed;
+ /* read the 2 comment lines */
+ fgets (tmp_buffer, sizeof(tmp_buffer), fp);
+ fgets (tmp_buffer, sizeof(tmp_buffer), fp);
+ /* read all line until found eth0 */
+ while(fgets (tmp_buffer, sizeof(tmp_buffer), fp))
+ {
+ if((ptr = strchr (tmp_buffer, ':')) == NULL)
+ continue;
+ *ptr = '\0';
+ ptr++;
+ if((sscanf (tmp_buffer, "%s", name) == 1)
+ && !strncmp (name, ETH_IFNAME, strlen(ETH_IFNAME))
+ && (sscanf (ptr, "%Lu %Lu %lu %lu %lu %lu %*s %*s %Lu %Lu %lu %lu %lu %lu %lu %*s",
+ &rx_bytes,
+ &rx_packets,
+ (unsigned long int *)&eth_stats_cnf->rx_errors,
+ (unsigned long int *)&eth_stats_cnf->rx_dropped,
+ (unsigned long int *)&eth_stats_cnf->rx_overruns,
+ (unsigned long int *)&eth_stats_cnf->rx_frames,
+ &tx_bytes,
+ &tx_packets,
+ (unsigned long int *)&eth_stats_cnf->tx_errors,
+ (unsigned long int *)&eth_stats_cnf->tx_dropped,
+ (unsigned long int *)&eth_stats_cnf->tx_fifo,
+ (unsigned long int *)&eth_stats_cnf->tx_collisions,
+ (unsigned long int *)&eth_stats_cnf->tx_carrier) == 13))
+ {
+ eth_stats_cnf->rx_bytes_low = rx_bytes & 0xffffffff;
+ eth_stats_cnf->rx_bytes_high = (rx_bytes & 0xffffffff00000000LL) >> 32;
+ eth_stats_cnf->rx_packets_low = rx_packets & 0xffffffff;
+ eth_stats_cnf->rx_packets_high = (rx_packets & 0xffffffff00000000LL) >> 32;
+ eth_stats_cnf->tx_bytes_low = tx_bytes & 0xffffffff;
+ eth_stats_cnf->tx_bytes_high = (tx_bytes & 0xffffffff00000000LL) >> 32;
+ eth_stats_cnf->tx_packets_low = tx_packets & 0xffffffff;
+ eth_stats_cnf->tx_packets_high = (tx_packets & 0xffffffff00000000LL) >> 32;
+
+ //printf ( "name='%s', rx_bytes=%llu rx_errors=%lu\n", name, eth_stats_cnf->rx_bytes_low, (unsigned long int)eth_stats_cnf->rx_errors);
+ eth_stats_cnf->result = MME_RESULT_SUCCESS;
+ break;
+ }
+ }
+ fclose (fp);
+ }
+
+ failed:
+ bridge_send_to_br (ctx, (uint8_t *)confirm, sizeof(MME_t) + sizeof(vs_eth_stats_cnf_t));
+ return TO_DROP;
+}