blob: e96ad7a26e61e84c2fa192728b6b4fc559f9af62 [file] [log] [blame]
Harald Welteccea8dd2016-12-24 10:27:55 +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 */
Harald Welte0e509162016-12-24 01:32:10 +010018
19#include <stdlib.h>
20#include <stdio.h>
21#include <string.h>
22
23#include <osmocom/core/msgb.h>
Harald Welte6fc7f682016-12-24 10:01:28 +010024#include <osmocom/core/bit16gen.h>
25#include <osmocom/core/bit32gen.h>
Harald Welte0e509162016-12-24 01:32:10 +010026
Harald Welte84ec50f2016-12-24 10:16:00 +010027#include "protocol/protocol.h"
Harald Welte0e509162016-12-24 01:32:10 +010028#include "diag_msg.h"
Harald Welte022c45a2017-01-01 16:28:57 +010029#include "diag_cmd.h"
Harald Welte84ec50f2016-12-24 10:16:00 +010030#include "protocol/diagcmd.h"
Harald Welte0e509162016-12-24 01:32:10 +010031
Harald Welte6fc7f682016-12-24 10:01:28 +010032struct diag_set_rt_mask_req {
33 uint8_t cmd_code;
34 uint8_t sub_cmd;
35 uint16_t ssid_start;
36 uint16_t ssid_end;
37 uint16_t _pad;
38 uint32_t runtime_mask[1];
39};
40
41#define MSG_EXT_SUBCMD_SET_RT_MASK 4
42
43struct msgb *gen_msg_config_set_rt_mask(uint16_t ssid, uint32_t runtime_mask)
44{
45 struct msgb *msg = msgb_alloc(DIAG_MAX_REQ_SIZE, "Diag Msg Config");
46 struct diag_set_rt_mask_req *dsrmr;
47
48 msg->l2h = msgb_put(msg, sizeof(*dsrmr));
Harald Welte4ae09362017-01-07 15:54:41 +010049 dsrmr = (struct diag_set_rt_mask_req *) msgb_l2(msg);
Harald Welte6fc7f682016-12-24 10:01:28 +010050 dsrmr->cmd_code = DIAG_EXT_MSG_CONFIG_F;
51 dsrmr->sub_cmd = MSG_EXT_SUBCMD_SET_RT_MASK;
52 osmo_store16le(ssid, &dsrmr->ssid_start);
53 osmo_store16le(ssid, &dsrmr->ssid_end);
54 osmo_store32le(runtime_mask, &dsrmr->runtime_mask[0]);
55
56 return msg;
57}
58
59int diag_msg_config_set_rt_mask(struct diag_instance *di, uint16_t ssid, uint32_t runtime_mask)
60{
61 struct msgb *msg = gen_msg_config_set_rt_mask(ssid, runtime_mask);
Harald Weltedc2cafc2017-01-01 11:15:35 +010062 struct msgb *rx;
Harald Weltef1801992017-01-01 11:47:31 +010063 struct diag_set_rt_mask_req *res;
64 int rc = 0;
Harald Weltedc2cafc2017-01-01 11:15:35 +010065
66 rx = diag_transceive_msg(di, msg);
Harald Weltef1801992017-01-01 11:47:31 +010067 res = (struct diag_set_rt_mask_req *) (msgb_l2(msg)+1);
Harald Welte651d4d82017-01-02 00:53:11 +010068 if ((rx->l2h[0] != DIAG_EXT_MSG_CONFIG_F) || res->cmd_code != MSG_EXT_SUBCMD_SET_RT_MASK ||
Harald Weltef1801992017-01-01 11:47:31 +010069 res->sub_cmd != MSG_EXT_SUBCMD_SET_RT_MASK ||
70 osmo_load16le(&res->ssid_start) != ssid ||
71 osmo_load16le(&res->ssid_end) != ssid ||
72 osmo_load32le(&res->runtime_mask) != runtime_mask) {
73 fprintf(stderr, "Error setting RT mask\n");
74 rc = -1;
75 }
Harald Weltedc2cafc2017-01-01 11:15:35 +010076 msgb_free(rx);
Harald Welte6fc7f682016-12-24 10:01:28 +010077
Harald Weltef1801992017-01-01 11:47:31 +010078 return rc;
Harald Welte6fc7f682016-12-24 10:01:28 +010079}
Harald Welte0e509162016-12-24 01:32:10 +010080
81/* handler for EXT MSG */
Harald Welte022c45a2017-01-01 16:28:57 +010082static void diag_rx_ext_msg_f(struct diag_instance *di, struct msgb *msgb)
Harald Welte0e509162016-12-24 01:32:10 +010083{
Harald Welte70ff72d2017-01-21 11:20:07 +010084 uint8_t *data = msgb_data(msgb);
Harald Welte0e509162016-12-24 01:32:10 +010085 const size_t len = msgb_length(msgb);
Harald Welte70ff72d2017-01-21 11:20:07 +010086 struct ext_log_msg *msg;
87 char *file = NULL, *fmt;
Harald Welte0e509162016-12-24 01:32:10 +010088 unsigned int num_args;
89
90 if (len < sizeof(struct ext_log_msg)) {
91 printf("too short ext_log_msg.\n");
Harald Welte022c45a2017-01-01 16:28:57 +010092 return;
Harald Welte0e509162016-12-24 01:32:10 +010093 }
94
95 msg = (struct ext_log_msg *) data;
Harald Welte89c159c2017-01-01 16:42:12 +010096 num_args = msg->hdr.num_args;
Harald Welte70ff72d2017-01-21 11:20:07 +010097 fmt = (char *) msg->params + num_args*sizeof(msg->params[0]);
Harald Welte0e509162016-12-24 01:32:10 +010098 file = fmt + strlen(fmt) + 1;
99
Harald Welte7af93aa2017-01-01 12:00:38 +0100100 printf("MSG(%u|%u|%s:%u): ", osmo_load16le(&msg->subsys_id),
Harald Welte89c159c2017-01-01 16:42:12 +0100101 diag_ts_to_epoch(osmo_load64le(&msg->hdr.timestamp)),
Harald Welte7af93aa2017-01-01 12:00:38 +0100102 file, osmo_load16le(&msg->line_nr));
Harald Welteb8a70982017-01-08 13:45:54 +0100103
104 /* replace all '%s' with '%p', as %s obviously doesn't work */
105 for (char *cur = fmt; cur && (cur < fmt + strlen(fmt)); cur = strstr(fmt, "%s")) {
106 cur[1] = 'p';
107 }
108
Harald Welte0e509162016-12-24 01:32:10 +0100109 switch (num_args) {
110 case 0:
111 fputs(fmt, stdout);
112 break;
113 case 1:
Harald Welte7af93aa2017-01-01 12:00:38 +0100114 printf(fmt, osmo_load32le(&msg->params[0]));
Harald Welte0e509162016-12-24 01:32:10 +0100115 break;
116 case 2:
Harald Welte7af93aa2017-01-01 12:00:38 +0100117 printf(fmt, osmo_load32le(&msg->params[0]),
118 osmo_load32le(&msg->params[1]));
Harald Welte0e509162016-12-24 01:32:10 +0100119 break;
120 case 3:
Harald Welte7af93aa2017-01-01 12:00:38 +0100121 printf(fmt, osmo_load32le(&msg->params[0]),
122 osmo_load32le(&msg->params[1]),
123 osmo_load32le(&msg->params[2]));
Harald Welte0e509162016-12-24 01:32:10 +0100124 break;
125 case 4:
Harald Welte7af93aa2017-01-01 12:00:38 +0100126 printf(fmt, osmo_load32le(&msg->params[0]),
127 osmo_load32le(&msg->params[1]),
128 osmo_load32le(&msg->params[2]),
129 osmo_load32le(&msg->params[3]));
Harald Welte0e509162016-12-24 01:32:10 +0100130 break;
131 }
132 fputc('\n', stdout);
Harald Welte0e509162016-12-24 01:32:10 +0100133}
134
Harald Welte89c159c2017-01-01 16:42:12 +0100135static void diag_rx_ext_msg_terse_f(struct diag_instance *di, struct msgb *msgb)
136{
137 const uint8_t *data = msgb_data(msgb);
138 const size_t len = msgb_length(msgb);
139 const struct qsr_ext_msg_terse *msg;
140 unsigned int num_args;
141
142 if (len < sizeof(struct qsr_ext_msg_terse)) {
143 printf("too short ext_log_msg.\n");
144 return;
145 }
146
147 msg = (struct qsr_ext_msg_terse *) data;
148 num_args = msg->hdr.num_args;
149
150 printf("MSG_QS(%u|%u|%08x:%u): ", osmo_load16le(&msg->subsys_id),
151 diag_ts_to_epoch(osmo_load64le(&msg->hdr.timestamp)),
152 osmo_load32le(&msg->hash), osmo_load16le(&msg->line_nr));
153 switch (num_args) {
154 case 0:
155 fputs("", stdout);
156 break;
157 case 1:
158 printf("%08x", osmo_load32le(&msg->params[0]));
159 break;
160 case 2:
161 printf("%08x %08x", osmo_load32le(&msg->params[0]),
162 osmo_load32le(&msg->params[1]));
163 break;
164 case 3:
165 printf("%08x %08x %08x", osmo_load32le(&msg->params[0]),
166 osmo_load32le(&msg->params[1]),
167 osmo_load32le(&msg->params[2]));
168 break;
169 case 4:
170 printf("%08x %08x %08x %08x", osmo_load32le(&msg->params[0]),
171 osmo_load32le(&msg->params[1]),
172 osmo_load32le(&msg->params[2]),
173 osmo_load32le(&msg->params[3]));
174 break;
175 }
176 fputc('\n', stdout);
177}
178
179
Harald Welte022c45a2017-01-01 16:28:57 +0100180struct diag_cmd_dispatch_tbl cmd_tbl[] = {
181 { DIAG_EXT_MSG_F, diag_rx_ext_msg_f },
Harald Welte89c159c2017-01-01 16:42:12 +0100182 { DIAG_QSR_EXT_MSG_TERSE_F, diag_rx_ext_msg_terse_f },
Harald Welte022c45a2017-01-01 16:28:57 +0100183};
Harald Welte0e509162016-12-24 01:32:10 +0100184
Harald Welte022c45a2017-01-01 16:28:57 +0100185static __attribute__((constructor)) void on_dso_load_msg(void)
186{
187 diag_cmd_reg_dispatch(cmd_tbl, ARRAY_SIZE(cmd_tbl));
188}