blob: 7acbe8d1ff74179d6da9e6eff59abd2f73219f42 [file] [log] [blame]
Harald Welte3710dcc2017-01-21 23:53:15 +01001/*
2 * (C) 2013-2016 by Harald Welte <laforge@gnumonks.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <stdio.h>
20#include <string.h>
21#include <stdint.h>
22#include <osmocom/core/msgb.h>
23
24#include "diag_cmd.h"
25#include "protocol/protocol.h"
26#include "protocol/diagcmd.h"
27
28/***********************************************************************
29 * EVENT Configuration / Protocol
30 ***********************************************************************/
31
32struct diag_event_mask_set_req {
33 uint8_t cmd_code;
34 uint8_t pad[3];
35 uint8_t mask[0];
36} __attribute__((packed));
37
38struct diag_event_cfg_req {
39 uint8_t cmd_code;
40 uint8_t enable;
41} __attribute__((packed));
42
43static struct msgb *gen_event_set_mask(uint32_t last_item)
44{
45 struct msgb *msg = msgb_alloc(DIAG_MAX_REQ_SIZE, "Diag Event Cfg");
46 struct diag_event_mask_set_req *demsr;
47
48 msg->l2h = msgb_put(msg, sizeof(*demsr));
49 demsr = (struct diag_event_mask_set_req *) msg->l2h;
50 demsr->cmd_code = DIAG_EVENT_MASK_SET_F;
51 msg->l3h = msgb_put(msg, bytes_rqd_for_bit(last_item));
52
53 return msg;
54}
55
56int diag_event_set_bit(struct msgb *msg, uint32_t bit_in)
57{
58 struct diag_event_mask_set_req *demsr;
59 demsr = (struct diag_event_mask_set_req *) msg->l2h;
60 uint8_t *mask = demsr->mask;
61 unsigned int byte = bit_in / 8;
62 unsigned int bit = bit_in % 8;
63
64 if (mask + byte > msg->tail) {
65 fprintf(stderr, "bit %u is outside event mask!\n", bit_in);
66 return -1;
67 }
68
69 mask[byte] |= (1 << bit);
70
71 return 0;
72}
73
74struct diag_event_id {
75 uint16_t id:12,
76 _pad:1,
77 payload_len:2, /* 0x2000, 0x4000 */
78 ts_trunc:1; /* 0x8000 */
79} __attribute__ ((packed));
80
81struct diag_event_report_event {
82 struct diag_event_id event_id;
83 uint64_t timestamp;
84 uint8_t payload[0];
85} __attribute__ ((packed));
86
87struct diag_event_report_event_trunc {
88 struct diag_event_id event_id;
89 uint16_t timestamp_trunc;
90 uint8_t payload[0];
91} __attribute__ ((packed));
92
93struct diag_event_report {
94 uint8_t cmd_code;
95 uint16_t len;
96 struct diag_event_report_event events[0];
97} __attribute__ ((packed));
98
99static void diag_rx_event_report_f(struct diag_instance *di, struct msgb *msg)
100{
101 struct diag_event_report *erep = (struct diag_event_report *) msgb_l2(msg);
102 uint16_t erep_len = osmo_load16le(&erep->len);
103 uint8_t *cur;
104
105 //printf("EVENT (erep_len=%u): %s\n", erep_len, msgb_hexdump(msg));
106
107 for (cur = (uint8_t *)erep->events; cur < (uint8_t *)erep->events + erep_len;) {
108 uint16_t _eid = osmo_load16le(cur);
109 struct diag_event_id *event_id = (struct diag_event_id *)&_eid;
110
111 if (event_id->ts_trunc) {
112 struct diag_event_report_event_trunc *ret;
113 ret = (struct diag_event_report_event_trunc *) cur;
114 cur += sizeof(*ret);
115 printf("EVENT-TRUNC(0x%04x|FIXME)", event_id->id);
116 } else {
117 struct diag_event_report_event *re;
118 re = (struct diag_event_report_event *) cur;
119 cur += sizeof(*re);
120 uint64_t ts = osmo_load64le(&re->timestamp);
121
122 printf("EVENT(0x%04x|%u|%u)", event_id->id,
123 diag_ts_to_epoch(ts), diag_ts_to_fn(ts));
124 }
125 switch (event_id->payload_len) {
126 case 0:
127 printf("\n");
128 break;
129 case 1:
130 printf(": 0x%02x\n", cur[0]);
131 cur += 1;
132 break;
133 case 2:
134 printf(": 0x%02x, 0x%02x\n", cur[0], cur[1]);
135 cur += 2;
136 break;
137 case 3:
138 printf(": %s\n", osmo_hexdump(cur+1, *cur));
139 cur += *cur + 1;
140 break;
141 }
142 }
143
144#if 0
145 for (i = 0; (i+1)*sizeof(struct diag_event_report_event) <= erep_len; i++) {
146 struct diag_event_report_event *evt = &erep->events[i];
147 uint16_t event_id = osmo_load16le(&evt->event_id);
148 }
149#endif
150}
151
152static const struct diag_cmd_dispatch_tbl cmd_tbl[] = {
153 { DIAG_EVENT_REPORT_F, diag_rx_event_report_f },
154};
155
156static __attribute__((constructor)) void on_dso_load_event(void)
157{
158 diag_cmd_reg_dispatch(cmd_tbl, ARRAY_SIZE(cmd_tbl));
159}