diff --git a/openbsc/include/openbsc/Makefile.am b/openbsc/include/openbsc/Makefile.am index 6a8778231..259e6d6f5 100644 --- a/openbsc/include/openbsc/Makefile.am +++ b/openbsc/include/openbsc/Makefile.am @@ -5,7 +5,8 @@ noinst_HEADERS = abis_nm.h abis_rsl.h db.h gsm_04_08.h gsm_data.h \ ipaccess.h rs232.h openbscdefines.h rtp_proxy.h \ bsc_rll.h mncc.h transaction.h ussd.h gsm_04_80.h \ silent_call.h mgcp.h meas_rep.h rest_octets.h \ - system_information.h handover.h mgcp_internal.h + system_information.h handover.h mgcp_internal.h \ + vty.h openbsc_HEADERS = gsm_04_08.h meas_rep.h bsc_api.h openbscdir = $(includedir)/openbsc diff --git a/openbsc/include/openbsc/vty.h b/openbsc/include/openbsc/vty.h new file mode 100644 index 000000000..40e219162 --- /dev/null +++ b/openbsc/include/openbsc/vty.h @@ -0,0 +1,6 @@ +#ifndef OPENBSC_VTY_H +#define OPENBSC_VTY_H + +void openbsc_vty_add_cmds(void); + +#endif diff --git a/openbsc/include/sccp/sccp.h b/openbsc/include/sccp/sccp.h index 643479adc..604a2ac72 100644 --- a/openbsc/include/sccp/sccp.h +++ b/openbsc/include/sccp/sccp.h @@ -94,7 +94,7 @@ struct sccp_connection { * call sccp_system_incoming for incoming data (from the network) * sccp will call outgoing whenever outgoing data exists */ -int sccp_system_init(int (*outgoing)(struct msgb *data, void *ctx), void *context); +int sccp_system_init(void (*outgoing)(struct msgb *data, void *ctx), void *context); int sccp_system_incoming(struct msgb *data); /** @@ -105,6 +105,11 @@ int sccp_connection_send_it(struct sccp_connection *connection); int sccp_connection_close(struct sccp_connection *connection, int cause); int sccp_connection_free(struct sccp_connection *connection); +/** + * internal.. + */ +int sccp_connection_force_free(struct sccp_connection *conn); + /** * Create a new socket. Set your callbacks and then call bind to open * the connection. diff --git a/openbsc/src/Makefile.am b/openbsc/src/Makefile.am index cbc809dc7..2c1d37a04 100644 --- a/openbsc/src/Makefile.am +++ b/openbsc/src/Makefile.am @@ -17,7 +17,7 @@ libbsc_a_SOURCES = abis_rsl.c abis_nm.c gsm_data.c gsm_04_08_utils.c \ input/misdn.c input/ipaccess.c \ talloc_ctx.c system_information.c rest_octets.c \ rtp_proxy.c bts_siemens_bs11.c bts_ipaccess_nanobts.c \ - bts_unknown.c bsc_version.c bsc_api.c + bts_unknown.c bsc_version.c bsc_api.c vty_interface_cmds.c libmsc_a_SOURCES = gsm_subscriber.c db.c telnet_interface.c \ mncc.c gsm_04_08.c gsm_04_11.c transaction.c \ @@ -42,7 +42,7 @@ ipaccess_config_LDADD = libbsc.a libmsc.a libbsc.a libvty.a -ldl -ldbi $(LIBCRYP isdnsync_SOURCES = isdnsync.c bsc_mgcp_SOURCES = mgcp/mgcp_main.c mgcp/mgcp_protocol.c mgcp/mgcp_network.c mgcp/mgcp_vty.c \ - debug.c telnet_interface.c + debug.c telnet_interface.c vty_interface_cmds.c bsc_mgcp_LDADD = libvty.a ipaccess_proxy_SOURCES = ipaccess/ipaccess-proxy.c debug.c diff --git a/openbsc/src/db.c b/openbsc/src/db.c index 312d0f233..8bf47ab38 100644 --- a/openbsc/src/db.c +++ b/openbsc/src/db.c @@ -288,6 +288,8 @@ struct gsm_subscriber *db_create_subscriber(struct gsm_network *net, char *imsi) return subscr; } +static_assert(sizeof(unsigned char) == sizeof(struct gsm48_classmark1), classmark1_size); + static int get_equipment_by_subscr(struct gsm_subscriber *subscr) { dbi_result result; @@ -316,9 +318,10 @@ static int get_equipment_by_subscr(struct gsm_subscriber *subscr) strncpy(equip->imei, string, sizeof(equip->imei)); string = dbi_result_get_string(result, "classmark1"); - if (string) - cm1 = atoi(string) & 0xff; - equip->classmark1 = *((struct gsm48_classmark1 *) &cm1); + if (string) { + cm1 = atoi(string) & 0xff; + memcpy(&equip->classmark1, &cm1, sizeof(equip->classmark1)); + } equip->classmark2_len = dbi_result_get_field_length(result, "classmark2"); cm2 = dbi_result_get_binary(result, "classmark2"); diff --git a/openbsc/src/input/misdn.c b/openbsc/src/input/misdn.c index 56930d498..83b01f2ca 100644 --- a/openbsc/src/input/misdn.c +++ b/openbsc/src/input/misdn.c @@ -262,7 +262,7 @@ static int handle_tsX_write(struct bsc_fd *bfd) ret = send(bfd->fd, tx_buf, sizeof(*hh) + BCHAN_TX_GRAN, 0); if (ret < sizeof(*hh) + BCHAN_TX_GRAN) - DEBUGP(DMIB, "send returns %d instead of %lu\n", ret, + DEBUGP(DMIB, "send returns %d instead of %zu\n", ret, sizeof(*hh) + BCHAN_TX_GRAN); return ret; diff --git a/openbsc/src/ipaccess/ipaccess-proxy.c b/openbsc/src/ipaccess/ipaccess-proxy.c index 73ce2df19..386081349 100644 --- a/openbsc/src/ipaccess/ipaccess-proxy.c +++ b/openbsc/src/ipaccess/ipaccess-proxy.c @@ -550,6 +550,7 @@ static int ipaccess_rcvmsg(struct ipa_proxy_conn *ipc, struct msgb *msg, } /* lookup BTS, create sign_link, ... */ + site_id = bts_id = trx_id = 0; parse_unitid((char *)TLVP_VAL(&tlvp, IPAC_IDTAG_UNIT), &site_id, &bts_id, &trx_id); ipbc = find_bts_by_unitid(ipp, site_id, bts_id); diff --git a/openbsc/src/mgcp/mgcp_main.c b/openbsc/src/mgcp/mgcp_main.c index 5e337e902..80b7b543c 100644 --- a/openbsc/src/mgcp/mgcp_main.c +++ b/openbsc/src/mgcp/mgcp_main.c @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -255,6 +256,7 @@ int bsc_vty_init(struct gsm_network *dummy) cmd_init(1); vty_init(); + openbsc_vty_add_cmds(); mgcp_vty_init(); return 0; } diff --git a/openbsc/src/sccp/sccp.c b/openbsc/src/sccp/sccp.c index b1da2c721..e0fd02e0e 100644 --- a/openbsc/src/sccp/sccp.c +++ b/openbsc/src/sccp/sccp.c @@ -45,7 +45,7 @@ const struct sockaddr_sccp sccp_ssn_bssap = { struct sccp_system { /* layer3 -> layer2 */ - int (*write_data)(struct msgb *data, void *context); + void (*write_data)(struct msgb *data, void *context); void *write_context; }; @@ -91,9 +91,9 @@ static struct sccp_data_callback *_find_ssn(u_int8_t ssn) } -static int _send_msg(struct msgb *msg) +static void _send_msg(struct msgb *msg) { - return sccp_system.write_data(msg, sccp_system.write_context); + sccp_system.write_data(msg, sccp_system.write_context); } /* @@ -499,7 +499,6 @@ static int _sccp_send_data(int class, const struct sockaddr_sccp *in, { struct sccp_data_unitdata *udt; u_int8_t *data; - int ret; if (msgb_l3len(payload) > 256) { DEBUGP(DSCCP, "The payload is too big for one udt\n"); @@ -533,10 +532,8 @@ static int _sccp_send_data(int class, const struct sockaddr_sccp *in, data[0] = msgb_l3len(payload); memcpy(&data[1], payload->l3h, msgb_l3len(payload)); - ret = _send_msg(msg); - msgb_free(msg); - - return ret; + _send_msg(msg); + return 0; } static int _sccp_handle_read(struct msgb *msgb) @@ -627,7 +624,6 @@ static int _sccp_send_refuse(struct sccp_source_reference *src_ref, int cause) struct msgb *msgb; struct sccp_connection_refused *ref; u_int8_t *data; - int ret; msgb = msgb_alloc_headroom(SCCP_MSG_SIZE, SCCP_MSG_HEADROOM, "sccp ref"); @@ -643,9 +639,8 @@ static int _sccp_send_refuse(struct sccp_source_reference *src_ref, int cause) data = msgb_put(msgb, 1); data[0] = SCCP_PNC_END_OF_OPTIONAL; - ret = _send_msg(msgb); - msgb_free(msgb); - return ret; + _send_msg(msgb); + return 0; } static int _sccp_send_connection_confirm(struct sccp_connection *connection) @@ -653,7 +648,6 @@ static int _sccp_send_connection_confirm(struct sccp_connection *connection) struct msgb *response; struct sccp_connection_confirm *confirm; u_int8_t *optional_data; - int ret; if (assign_source_local_reference(connection) != 0) return -1; @@ -677,11 +671,9 @@ static int _sccp_send_connection_confirm(struct sccp_connection *connection) optional_data = (u_int8_t *) msgb_put(response, 1); optional_data[0] = SCCP_PNC_END_OF_OPTIONAL; - ret = _send_msg(response); - msgb_free(response); - + _send_msg(response); _sccp_set_connection_state(connection, SCCP_CONNECTION_STATE_ESTABLISHED); - return ret; + return 0; } static int _sccp_send_connection_request(struct sccp_connection *connection, @@ -691,7 +683,6 @@ static int _sccp_send_connection_request(struct sccp_connection *connection, struct sccp_connection_request *req; u_int8_t *data; u_int8_t extra_size = 3 + 1; - int ret; if (msg && (msgb_l3len(msg) < 3 || msgb_l3len(msg) > 130)) { @@ -741,10 +732,8 @@ static int _sccp_send_connection_request(struct sccp_connection *connection, llist_add_tail(&connection->list, &sccp_connections); _sccp_set_connection_state(connection, SCCP_CONNECTION_STATE_REQUEST); - ret = _send_msg(request); - msgb_free(request); - - return ret; + _send_msg(request); + return 0; } static int _sccp_send_connection_data(struct sccp_connection *conn, struct msgb *_data) @@ -753,7 +742,6 @@ static int _sccp_send_connection_data(struct sccp_connection *conn, struct msgb struct sccp_data_form1 *dt1; u_int8_t *data; int extra_size; - int ret; if (msgb_l3len(_data) < 2 || msgb_l3len(_data) > 256) { DEBUGP(DSCCP, "data size too big, segmenting unimplemented.\n"); @@ -777,17 +765,14 @@ static int _sccp_send_connection_data(struct sccp_connection *conn, struct msgb data[0] = extra_size - 1; memcpy(&data[1], _data->l3h, extra_size - 1); - ret = _send_msg(msgb); - msgb_free(msgb); - - return ret; + _send_msg(msgb); + return 0; } static int _sccp_send_connection_it(struct sccp_connection *conn) { struct msgb *msgb; struct sccp_data_it *it; - int ret; msgb = msgb_alloc_headroom(SCCP_MSG_SIZE, SCCP_MSG_HEADROOM, "sccp it"); @@ -803,9 +788,8 @@ static int _sccp_send_connection_it(struct sccp_connection *conn) it->sequencing[0] = it->sequencing[1] = 0; it->credit = 0; - ret = _send_msg(msgb); - msgb_free(msgb); - return ret; + _send_msg(msgb); + return 0; } static int _sccp_send_connection_released(struct sccp_connection *conn, int cause) @@ -813,7 +797,6 @@ static int _sccp_send_connection_released(struct sccp_connection *conn, int caus struct msgb *msg; struct sccp_connection_released *rel; u_int8_t *data; - int ret; msg = msgb_alloc_headroom(SCCP_MSG_SIZE, SCCP_MSG_HEADROOM, "sccp: connection released"); @@ -832,10 +815,8 @@ static int _sccp_send_connection_released(struct sccp_connection *conn, int caus data[0] = SCCP_PNC_END_OF_OPTIONAL; _sccp_set_connection_state(conn, SCCP_CONNECTION_STATE_RELEASE); - ret = _send_msg(msg); - msgb_free(msg); - - return ret; + _send_msg(msg); + return 0; } /* @@ -982,7 +963,6 @@ static int _sccp_send_connection_release_complete(struct sccp_connection *connec { struct msgb *msgb; struct sccp_connection_release_complete *rlc; - int ret; msgb = msgb_alloc_headroom(SCCP_MSG_SIZE, SCCP_MSG_HEADROOM, "sccp rlc"); @@ -995,8 +975,7 @@ static int _sccp_send_connection_release_complete(struct sccp_connection *connec memcpy(&rlc->source_local_reference, &connection->source_local_reference, sizeof(struct sccp_source_reference)); - ret = _send_msg(msgb); - msgb_free(msgb); + _send_msg(msgb); /* * Remove from the list of active connections and set the state. User code @@ -1004,8 +983,7 @@ static int _sccp_send_connection_release_complete(struct sccp_connection *connec */ llist_del(&connection->list); _sccp_set_connection_state(connection, SCCP_CONNECTION_STATE_RELEASE_COMPLETE); - - return ret; + return 0; } /* connection released, send a released confirm */ @@ -1118,7 +1096,7 @@ found: } -int sccp_system_init(int (*outgoing)(struct msgb *data, void *ctx), void *ctx) +int sccp_system_init(void (*outgoing)(struct msgb *data, void *ctx), void *ctx) { sccp_system.write_data = outgoing; sccp_system.write_context = ctx; @@ -1220,6 +1198,17 @@ int sccp_connection_free(struct sccp_connection *connection) return 0; } +int sccp_connection_force_free(struct sccp_connection *con) +{ + if (con->connection_state > SCCP_CONNECTION_STATE_NONE && + con->connection_state < SCCP_CONNECTION_STATE_RELEASE_COMPLETE) + llist_del(&con->list); + + con->connection_state = SCCP_CONNECTION_STATE_REFUSED; + sccp_connection_free(con); + return 0; +} + struct sccp_connection *sccp_connection_socket(void) { return talloc_zero(tall_sccp_ctx, struct sccp_connection); diff --git a/openbsc/src/vty_interface.c b/openbsc/src/vty_interface.c index f2ac12dcd..b5bdbc8c2 100644 --- a/openbsc/src/vty_interface.c +++ b/openbsc/src/vty_interface.c @@ -38,6 +38,7 @@ #include #include #include +#include static struct gsm_network *gsmnet; @@ -615,7 +616,7 @@ static void lchan_dump_vty(struct vty *vty, struct gsm_lchan *lchan) vty_out(vty, " No Subscriber%s", VTY_NEWLINE); if (is_ipaccess_bts(lchan->ts->trx->bts)) { struct in_addr ia; - ia.s_addr = lchan->abis_ip.bound_ip; + ia.s_addr = htonl(lchan->abis_ip.bound_ip); vty_out(vty, " Bound IP: %s Port %u RTP_TYPE2=%u CONN_ID=%u%s", inet_ntoa(ia), lchan->abis_ip.bound_port, lchan->abis_ip.rtp_payload2, lchan->abis_ip.conn_id, @@ -878,204 +879,6 @@ DEFUN(show_paging, return CMD_SUCCESS; } -static void _vty_output(struct log_target *tgt, const char *line) -{ - struct vty *vty = tgt->tgt_vty.vty; - vty_out(vty, "%s", line); - /* This is an ugly hack, but there is no easy way... */ - if (strchr(line, '\n')) - vty_out(vty, "\r"); -} - -struct log_target *log_target_create_vty(struct vty *vty) -{ - struct log_target *target; - - target = log_target_create(); - if (!target) - return NULL; - - target->tgt_vty.vty = vty; - target->output = _vty_output; - return target; -} - -DEFUN(enable_logging, - enable_logging_cmd, - "logging enable", - "Enables logging to this vty\n") -{ - struct telnet_connection *conn; - - conn = (struct telnet_connection *) vty->priv; - if (conn->dbg) { - vty_out(vty, "Logging already enabled.%s", VTY_NEWLINE); - return CMD_WARNING; - } - - conn->dbg = log_target_create_vty(vty); - if (!conn->dbg) - return CMD_WARNING; - - log_add_target(conn->dbg); - return CMD_SUCCESS; -} - -DEFUN(logging_fltr_imsi, - logging_fltr_imsi_cmd, - "logging filter imsi IMSI", - "Print all messages related to a IMSI\n") -{ - struct telnet_connection *conn; - - conn = (struct telnet_connection *) vty->priv; - if (!conn->dbg) { - vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); - return CMD_WARNING; - } - - log_set_imsi_filter(conn->dbg, argv[0]); - return CMD_SUCCESS; -} - -DEFUN(logging_fltr_all, - logging_fltr_all_cmd, - "logging filter all <0-1>", - "Print all messages to the console\n") -{ - struct telnet_connection *conn; - - conn = (struct telnet_connection *) vty->priv; - if (!conn->dbg) { - vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); - return CMD_WARNING; - } - - log_set_all_filter(conn->dbg, atoi(argv[0])); - return CMD_SUCCESS; -} - -DEFUN(logging_use_clr, - logging_use_clr_cmd, - "logging color <0-1>", - "Use color for printing messages\n") -{ - struct telnet_connection *conn; - - conn = (struct telnet_connection *) vty->priv; - if (!conn->dbg) { - vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); - return CMD_WARNING; - } - - log_set_use_color(conn->dbg, atoi(argv[0])); - return CMD_SUCCESS; -} - -DEFUN(logging_prnt_timestamp, - logging_prnt_timestamp_cmd, - "logging timestamp <0-1>", - "Print the timestamp of each message\n") -{ - struct telnet_connection *conn; - - conn = (struct telnet_connection *) vty->priv; - if (!conn->dbg) { - vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); - return CMD_WARNING; - } - - log_set_print_timestamp(conn->dbg, atoi(argv[0])); - return CMD_SUCCESS; -} - -/* FIXME: those have to be kept in sync with the log levels and categories */ -#define VTY_DEBUG_CATEGORIES "(rll|cc|mm|rr|rsl|nm|sms|pag|mncc|inp|mi|mib|mux|meas|sccp|msc|mgcp|ho|db|ref)" -#define VTY_DEBUG_LEVELS "(everything|debug|info|notice|error|fatal)" -DEFUN(logging_level, - logging_level_cmd, - "logging level " VTY_DEBUG_CATEGORIES " " VTY_DEBUG_LEVELS, - "Set the log level for a specified category\n") -{ - struct telnet_connection *conn; - int category = log_parse_category(argv[0]); - int level = log_parse_level(argv[1]); - - conn = (struct telnet_connection *) vty->priv; - if (!conn->dbg) { - vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); - return CMD_WARNING; - } - - if (category < 0) { - vty_out(vty, "Invalid category `%s'%s", argv[0], VTY_NEWLINE); - return CMD_WARNING; - } - - if (level < 0) { - vty_out(vty, "Invalid level `%s'%s", argv[1], VTY_NEWLINE); - return CMD_WARNING; - } - - conn->dbg->categories[category].enabled = 1; - conn->dbg->categories[category].loglevel = level; - - return CMD_SUCCESS; -} - -DEFUN(logging_set_category_mask, - logging_set_category_mask_cmd, - "logging set log mask MASK", - "Decide which categories to output.\n") -{ - struct telnet_connection *conn; - - conn = (struct telnet_connection *) vty->priv; - if (!conn->dbg) { - vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); - return CMD_WARNING; - } - - log_parse_category_mask(conn->dbg, argv[0]); - return CMD_SUCCESS; -} - -DEFUN(logging_set_log_level, - logging_set_log_level_cmd, - "logging set log level <0-8>", - "Set the global log level. The value 0 implies no filtering.\n") -{ - struct telnet_connection *conn; - - conn = (struct telnet_connection *) vty->priv; - if (!conn->dbg) { - vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); - return CMD_WARNING; - } - - log_set_log_level(conn->dbg, atoi(argv[0])); - return CMD_SUCCESS; -} - -DEFUN(diable_logging, - disable_logging_cmd, - "logging disable", - "Disables logging to this vty\n") -{ - struct telnet_connection *conn; - - conn = (struct telnet_connection *) vty->priv; - if (!conn->dbg) { - vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); - return CMD_WARNING; - } - - log_del_target(conn->dbg); - talloc_free(conn->dbg); - conn->dbg = NULL; - return CMD_SUCCESS; -} - DEFUN(show_stats, show_stats_cmd, "show statistics", @@ -1957,15 +1760,7 @@ int bsc_vty_init(struct gsm_network *net) install_element(VIEW_NODE, &show_paging_cmd); install_element(VIEW_NODE, &show_stats_cmd); - install_element(VIEW_NODE, &enable_logging_cmd); - install_element(VIEW_NODE, &disable_logging_cmd); - install_element(VIEW_NODE, &logging_fltr_imsi_cmd); - install_element(VIEW_NODE, &logging_fltr_all_cmd); - install_element(VIEW_NODE, &logging_use_clr_cmd); - install_element(VIEW_NODE, &logging_prnt_timestamp_cmd); - install_element(VIEW_NODE, &logging_set_category_mask_cmd); - install_element(VIEW_NODE, &logging_level_cmd); - install_element(VIEW_NODE, &logging_set_log_level_cmd); + openbsc_vty_add_cmds(); install_element(CONFIG_NODE, &cfg_net_cmd); install_node(&net_node, config_write_net); diff --git a/openbsc/src/vty_interface_cmds.c b/openbsc/src/vty_interface_cmds.c new file mode 100644 index 000000000..d4945840e --- /dev/null +++ b/openbsc/src/vty_interface_cmds.c @@ -0,0 +1,243 @@ +/* OpenBSC logging helper for the VTY */ +/* (C) 2009-2010 by Harald Welte + * (C) 2009-2010 by Holger Hans Peter Freyther + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include +#include + +#include + +#include +#include +#include + +#include + +static void _vty_output(struct log_target *tgt, const char *line) +{ + struct vty *vty = tgt->tgt_vty.vty; + vty_out(vty, "%s", line); + /* This is an ugly hack, but there is no easy way... */ + if (strchr(line, '\n')) + vty_out(vty, "\r"); +} + +struct log_target *log_target_create_vty(struct vty *vty) +{ + struct log_target *target; + + target = log_target_create(); + if (!target) + return NULL; + + target->tgt_vty.vty = vty; + target->output = _vty_output; + return target; +} + +DEFUN(enable_logging, + enable_logging_cmd, + "logging enable", + "Enables logging to this vty\n") +{ + struct telnet_connection *conn; + + conn = (struct telnet_connection *) vty->priv; + if (conn->dbg) { + vty_out(vty, "Logging already enabled.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + conn->dbg = log_target_create_vty(vty); + if (!conn->dbg) + return CMD_WARNING; + + log_add_target(conn->dbg); + return CMD_SUCCESS; +} + +DEFUN(logging_fltr_imsi, + logging_fltr_imsi_cmd, + "logging filter imsi IMSI", + "Print all messages related to a IMSI\n") +{ + struct telnet_connection *conn; + + conn = (struct telnet_connection *) vty->priv; + if (!conn->dbg) { + vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + log_set_imsi_filter(conn->dbg, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(logging_fltr_all, + logging_fltr_all_cmd, + "logging filter all <0-1>", + "Print all messages to the console\n") +{ + struct telnet_connection *conn; + + conn = (struct telnet_connection *) vty->priv; + if (!conn->dbg) { + vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + log_set_all_filter(conn->dbg, atoi(argv[0])); + return CMD_SUCCESS; +} + +DEFUN(logging_use_clr, + logging_use_clr_cmd, + "logging color <0-1>", + "Use color for printing messages\n") +{ + struct telnet_connection *conn; + + conn = (struct telnet_connection *) vty->priv; + if (!conn->dbg) { + vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + log_set_use_color(conn->dbg, atoi(argv[0])); + return CMD_SUCCESS; +} + +DEFUN(logging_prnt_timestamp, + logging_prnt_timestamp_cmd, + "logging timestamp <0-1>", + "Print the timestamp of each message\n") +{ + struct telnet_connection *conn; + + conn = (struct telnet_connection *) vty->priv; + if (!conn->dbg) { + vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + log_set_print_timestamp(conn->dbg, atoi(argv[0])); + return CMD_SUCCESS; +} + +/* FIXME: those have to be kept in sync with the log levels and categories */ +#define VTY_DEBUG_CATEGORIES "(rll|cc|mm|rr|rsl|nm|sms|pag|mncc|inp|mi|mib|mux|meas|sccp|msc|mgcp|ho|db|ref)" +#define VTY_DEBUG_LEVELS "(everything|debug|info|notice|error|fatal)" +DEFUN(logging_level, + logging_level_cmd, + "logging level " VTY_DEBUG_CATEGORIES " " VTY_DEBUG_LEVELS, + "Set the log level for a specified category\n") +{ + struct telnet_connection *conn; + int category = log_parse_category(argv[0]); + int level = log_parse_level(argv[1]); + + conn = (struct telnet_connection *) vty->priv; + if (!conn->dbg) { + vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + if (category < 0) { + vty_out(vty, "Invalid category `%s'%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + + if (level < 0) { + vty_out(vty, "Invalid level `%s'%s", argv[1], VTY_NEWLINE); + return CMD_WARNING; + } + + conn->dbg->categories[category].enabled = 1; + conn->dbg->categories[category].loglevel = level; + + return CMD_SUCCESS; +} + +DEFUN(logging_set_category_mask, + logging_set_category_mask_cmd, + "logging set log mask MASK", + "Decide which categories to output.\n") +{ + struct telnet_connection *conn; + + conn = (struct telnet_connection *) vty->priv; + if (!conn->dbg) { + vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + log_parse_category_mask(conn->dbg, argv[0]); + return CMD_SUCCESS; +} + +DEFUN(logging_set_log_level, + logging_set_log_level_cmd, + "logging set log level <0-8>", + "Set the global log level. The value 0 implies no filtering.\n") +{ + struct telnet_connection *conn; + + conn = (struct telnet_connection *) vty->priv; + if (!conn->dbg) { + vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + log_set_log_level(conn->dbg, atoi(argv[0])); + return CMD_SUCCESS; +} + +DEFUN(diable_logging, + disable_logging_cmd, + "logging disable", + "Disables logging to this vty\n") +{ + struct telnet_connection *conn; + + conn = (struct telnet_connection *) vty->priv; + if (!conn->dbg) { + vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE); + return CMD_WARNING; + } + + log_del_target(conn->dbg); + talloc_free(conn->dbg); + conn->dbg = NULL; + return CMD_SUCCESS; +} + +void openbsc_vty_add_cmds() +{ + install_element(VIEW_NODE, &enable_logging_cmd); + install_element(VIEW_NODE, &disable_logging_cmd); + install_element(VIEW_NODE, &logging_fltr_imsi_cmd); + install_element(VIEW_NODE, &logging_fltr_all_cmd); + install_element(VIEW_NODE, &logging_use_clr_cmd); + install_element(VIEW_NODE, &logging_prnt_timestamp_cmd); + install_element(VIEW_NODE, &logging_set_category_mask_cmd); + install_element(VIEW_NODE, &logging_level_cmd); + install_element(VIEW_NODE, &logging_set_log_level_cmd); + +} diff --git a/openbsc/tests/debug/debug_test.c b/openbsc/tests/debug/debug_test.c index 695d65c0b..f3e483703 100644 --- a/openbsc/tests/debug/debug_test.c +++ b/openbsc/tests/debug/debug_test.c @@ -38,4 +38,6 @@ int main(int argc, char** argv) DEBUGP(DRLL, "You should see this\n"); DEBUGP(DCC, "You should see this\n"); DEBUGP(DMM, "You should not see this\n"); + + return 0; } diff --git a/openbsc/tests/sccp/sccp_test.c b/openbsc/tests/sccp/sccp_test.c index eb41d3eaf..0c2adc83f 100644 --- a/openbsc/tests/sccp/sccp_test.c +++ b/openbsc/tests/sccp/sccp_test.c @@ -354,14 +354,14 @@ int sccp_read_cb(struct msgb *data, unsigned len, void *context) return 0; } -int sccp_write_cb(struct msgb *data, void *ctx) +void sccp_write_cb(struct msgb *data, void *ctx) { int i = 0; const u_int8_t *got, *wanted; if (test_data[current_test].response == NULL) { FAIL("Didn't expect write callback\n"); - return -1; + goto exit; } else if (test_data[current_test].response_length != msgb_l2len(data)) { FAIL("Size does not match. Got: %d Wanted: %d\n", msgb_l2len(data), test_data[current_test].response_length); @@ -374,12 +374,14 @@ int sccp_write_cb(struct msgb *data, void *ctx) if (got[i] != wanted[i]) { FAIL("Failed to compare byte. Got: 0x%x Wanted: 0x%x at %d\n", got[i], wanted[i], i); - return -1; + goto exit; } } write_called = 1; - return 0; + +exit: + msgb_free(data); } void sccp_c_read(struct sccp_connection *connection, struct msgb *msgb, unsigned int len) @@ -409,7 +411,7 @@ int sccp_accept_cb(struct sccp_connection *connection, void *user_data) return 0; } -static int sccp_udt_write_cb(struct msgb *data, void *context) +static void sccp_udt_write_cb(struct msgb *data, void *context) { const u_int8_t *got, *wanted; int i; @@ -419,7 +421,7 @@ static int sccp_udt_write_cb(struct msgb *data, void *context) if (send_data[current_test].length != msgb_l2len(data)) { FAIL("Size does not match. Got: %d Wanted: %d\n", msgb_l2len(data), send_data[current_test].length); - return -1; + goto exit; } got = &data->l2h[0]; @@ -429,12 +431,14 @@ static int sccp_udt_write_cb(struct msgb *data, void *context) if (got[i] != wanted[i]) { FAIL("Failed to compare byte. Got: 0x%x Wanted: 0x%x at %d\n", got[i], wanted[i], i); - return -1; + goto exit; } } matched = 1; - return 0; + +exit: + msgb_free(data); } static void test_sccp_system(void) @@ -504,11 +508,11 @@ static int sccp_udt_read(struct msgb *data, unsigned int len, void *context) return 0; } -static int sccp_write_loop(struct msgb *data, void *context) +static void sccp_write_loop(struct msgb *data, void *context) { /* send it back to us */ sccp_system_incoming(data); - return 0; + msgb_free(data); } static void test_sccp_udt_communication(void)