blob: a8d74f582b3f63793fbb05444175555fb3336582 [file] [log] [blame]
Neels Hofmeyrb2553eb2019-11-20 02:36:45 +01001/* Copyright 2019 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
2 *
3 * All Rights Reserved
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#pragma once
20
21#include <osmocom/gsm/gsup.h>
Neels Hofmeyr0d28d852019-12-04 01:04:32 +010022#include <osmocom/gsupclient/gsup_peer_id.h>
Neels Hofmeyrb2553eb2019-11-20 02:36:45 +010023
24struct osmo_gsup_req;
25
26#define LOG_GSUP_REQ_CAT_SRC(req, subsys, level, file, line, fmt, args...) \
27 LOGPSRC(subsys, level, file, line, "GSUP %u: %s: IMSI-%s %s: " fmt, \
28 (req) ? (req)->nr : 0, \
Neels Hofmeyr0d28d852019-12-04 01:04:32 +010029 (req) ? osmo_gsup_peer_id_to_str(&(req)->source_name) : "NULL", \
Neels Hofmeyrb2553eb2019-11-20 02:36:45 +010030 (req) ? (req)->gsup.imsi : "NULL", \
31 (req) ? osmo_gsup_message_type_name((req)->gsup.message_type) : "NULL", \
32 ##args)
33#define LOG_GSUP_REQ_CAT(req, subsys, level, fmt, args...) \
34 LOG_GSUP_REQ_CAT_SRC(req, subsys, level, __FILE__, __LINE__, fmt, ##args)
35
36#define LOG_GSUP_REQ_SRC(req, level, file, line, fmt, args...) \
37 LOG_GSUP_REQ_CAT_SRC(req, DLGSUP, level, file, line, fmt, ##args)
38
39#define LOG_GSUP_REQ(req, level, fmt, args...) \
40 LOG_GSUP_REQ_SRC(req, level, __FILE__, __LINE__, fmt, ##args)
41
42typedef void (*osmo_gsup_req_send_response_t)(struct osmo_gsup_req *req, struct osmo_gsup_message *response);
43
44/* Keep track of an incoming request, to route back a response when it is ready.
45 * Particularly, a GSUP response to a request must contain various bits of information that need to be copied from the
46 * request for proxy/routing to work and for session states to remain valid. That is the main reason why (almost) all
47 * GSUP request/response should go through an osmo_gsup_req, even if it is handled synchronously.
48 */
49struct osmo_gsup_req {
50 /* The incoming GSUP message in decoded form. */
51 const struct osmo_gsup_message gsup;
52
53 /* Decoding result code. If decoding failed, this will be != 0. */
54 int decode_rc;
55
56 /* The ultimate source of this message: the source_name form the GSUP message, or, if not present, then the
57 * immediate GSUP peer. GSUP messages going via a proxy reflect the initial source in the source_name.
58 * This source_name is implicitly added to the routes for the conn the message was received on. */
Neels Hofmeyr0d28d852019-12-04 01:04:32 +010059 struct osmo_gsup_peer_id source_name;
Neels Hofmeyrb2553eb2019-11-20 02:36:45 +010060
61 /* If the source_name is not an immediate GSUP peer, this is set to the closest intermediate peer between here
62 * and source_name. */
Neels Hofmeyr0d28d852019-12-04 01:04:32 +010063 struct osmo_gsup_peer_id via_proxy;
Neels Hofmeyrb2553eb2019-11-20 02:36:45 +010064
65 /* Identify this request by number, for logging. */
66 unsigned int nr;
67
68 /* osmo_gsup_req can be used by both gsup_server and gsup_client. The individual method of actually sending a
69 * GSUP message is provided by this callback. */
70 osmo_gsup_req_send_response_t send_response_cb;
71
72 /* User supplied data pointer, may be used to provide context to send_response_cb(). */
73 void *cb_data;
74
75 /* List entry that can be used to keep a list of osmo_gsup_req instances; not used directly by osmo_gsup_req.c,
76 * it is up to using implementations to keep a list. If this is non-NULL, osmo_gsup_req_free() calls
77 * llist_del() on this. */
78 struct llist_head entry;
79
80 /* A decoded GSUP message still points into the received msgb. For a decoded osmo_gsup_message to remain valid,
81 * we also need to keep the msgb. */
82 struct msgb *msg;
83};
84
Neels Hofmeyr0d28d852019-12-04 01:04:32 +010085struct osmo_gsup_req *osmo_gsup_req_new(void *ctx, const struct osmo_gsup_peer_id *from_peer, struct msgb *msg,
Neels Hofmeyrb2553eb2019-11-20 02:36:45 +010086 osmo_gsup_req_send_response_t send_response_cb, void *cb_data,
87 struct llist_head *add_to_list);
88void osmo_gsup_req_free(struct osmo_gsup_req *req);
89
90/*! Call _osmo_gsup_req_respond() to convey the sender's source file and line in the logs. */
91#define osmo_gsup_req_respond(REQ, RESPONSE, ERROR, FINAL_RESPONSE) \
92 _osmo_gsup_req_respond(REQ, RESPONSE, ERROR, FINAL_RESPONSE, __FILE__, __LINE__)
93int _osmo_gsup_req_respond(struct osmo_gsup_req *req, struct osmo_gsup_message *response,
94 bool error, bool final_response, const char *file, int line);
95
96/*! Call _osmo_gsup_req_respond_msgt() to convey the sender's source file and line in the logs. */
97#define osmo_gsup_req_respond_msgt(REQ, MESSAGE_TYPE, FINAL_RESPONSE) \
98 _osmo_gsup_req_respond_msgt(REQ, MESSAGE_TYPE, FINAL_RESPONSE, __FILE__, __LINE__)
99int _osmo_gsup_req_respond_msgt(struct osmo_gsup_req *req, enum osmo_gsup_message_type message_type,
100 bool final_response, const char *file, int line);
101
102/*! Log an error message, and call _osmo_gsup_req_respond() to convey the sender's source file and line in the logs. */
103#define osmo_gsup_req_respond_err(REQ, CAUSE, FMT, args...) do { \
104 LOG_GSUP_REQ(REQ, LOGL_ERROR, "%s: " FMT "\n", \
105 get_value_string(gsm48_gmm_cause_names, CAUSE), ##args); \
106 _osmo_gsup_req_respond_err(REQ, CAUSE, __FILE__, __LINE__); \
107 } while(0)
108void _osmo_gsup_req_respond_err(struct osmo_gsup_req *req, enum gsm48_gmm_cause cause,
109 const char *file, int line);
110
111int osmo_gsup_make_response(struct osmo_gsup_message *reply,
112 const struct osmo_gsup_message *rx, bool error, bool final_response);
113
114size_t osmo_gsup_message_to_str_buf(char *buf, size_t bufsize, const struct osmo_gsup_message *msg);
115char *osmo_gsup_message_to_str_c(void *ctx, const struct osmo_gsup_message *msg);