blob: 496e1f4f745099a9efc4b04e52a95a4f913b9cc4 [file] [log] [blame]
Harald Welte3dcdd202019-03-09 13:06:46 +01001/* (C) 2018-2019 by Harald Welte <laforge@gnumonks.org>
2 *
3 * All Rights Reserved
4 *
5 * SPDX-License-Identifier: GPL-2.0+
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 */
Harald Welte2ff0ab92018-08-17 22:10:49 +020022
23#include <errno.h>
24#include <string.h>
Harald Weltece638d82019-03-17 09:36:04 +010025#include <signal.h>
Harald Welte2ff0ab92018-08-17 22:10:49 +020026
Harald Welte228af8a2019-03-08 22:20:21 +010027#define _GNU_SOURCE
28#include <getopt.h>
29
Harald Welte2ff0ab92018-08-17 22:10:49 +020030#include <talloc.h>
31
32#include <osmocom/core/msgb.h>
33#include <osmocom/core/fsm.h>
34#include <osmocom/core/utils.h>
35#include <osmocom/core/logging.h>
36#include <osmocom/core/application.h>
37
38#include <osmocom/abis/ipa.h>
39#include <osmocom/gsm/protocol/ipaccess.h>
40
41#include "rspro_util.h"
Harald Welte24173fb2018-08-24 20:37:28 +020042#include "client.h"
Harald Welte61d98e92019-03-03 15:43:07 +010043#include "debug.h"
Harald Welte2ff0ab92018-08-17 22:10:49 +020044
Harald Welted5a87292020-02-13 16:44:56 +010045static int bankd_handle_rx(struct rspro_server_conn *bankdc, const RsproPDU_t *pdu)
Harald Welte2ff0ab92018-08-17 22:10:49 +020046{
Harald Welte24173fb2018-08-24 20:37:28 +020047 switch (pdu->msg.present) {
48 case RsproPDUchoice_PR_connectClientRes:
Harald Weltee56f2b92019-03-02 17:02:13 +010049 /* Store 'identity' of bankd to in peer_comp_id */
Harald Welted5a87292020-02-13 16:44:56 +010050 rspro_comp_id_retrieve(&bankdc->peer_comp_id, &pdu->msg.choice.connectClientRes.identity);
51 osmo_fsm_inst_dispatch(bankdc->fi, SRVC_E_CLIENT_CONN_RES, (void *) pdu);
Harald Welte24173fb2018-08-24 20:37:28 +020052 break;
Harald Welted5a87292020-02-13 16:44:56 +010053 case RsproPDUchoice_PR_tpduCardToModem:
54 case RsproPDUchoice_PR_setAtrReq:
Harald Welte1200c822020-02-13 20:43:27 +010055 return client_user_bankd_handle_rx(bankdc, pdu);
Harald Welte24173fb2018-08-24 20:37:28 +020056 default:
Harald Welted5a87292020-02-13 16:44:56 +010057 LOGPFSML(bankdc->fi, LOGL_ERROR, "Unknown/Unsupported RSPRO PDU %s\n",
58 rspro_msgt_name(pdu));
Harald Welte24173fb2018-08-24 20:37:28 +020059 return -1;
60 }
61
62 return 0;
Harald Welte2ff0ab92018-08-17 22:10:49 +020063}
64
Harald Welte8e46ab62020-02-14 12:55:43 +010065static struct bankd_client *g_client;
Harald Welte2ff0ab92018-08-17 22:10:49 +020066static void *g_tall_ctx;
67void __thread *talloc_asn1_ctx;
Harald Welte43ab79f2018-10-03 23:34:21 +020068int asn_debug;
Harald Welte2ff0ab92018-08-17 22:10:49 +020069
Harald Weltee56f2b92019-03-02 17:02:13 +010070/* handle incoming messages from server */
71static int srvc_handle_rx(struct rspro_server_conn *srvc, const RsproPDU_t *pdu)
72{
Harald Welte8e46ab62020-02-14 12:55:43 +010073 struct bankd_client *bc = srvc2bankd_client(srvc);
Harald Weltee56f2b92019-03-02 17:02:13 +010074 RsproPDU_t *resp;
75
76 switch (pdu->msg.present) {
77 case RsproPDUchoice_PR_connectClientRes:
78 /* Store 'identity' of server in srvc->peer_comp_id */
79 rspro_comp_id_retrieve(&srvc->peer_comp_id, &pdu->msg.choice.connectClientRes.identity);
80 osmo_fsm_inst_dispatch(srvc->fi, SRVC_E_CLIENT_CONN_RES, (void *) pdu);
81 break;
Harald Welted571a3e2019-03-11 22:09:50 +010082 case RsproPDUchoice_PR_configClientIdReq:
Harald Weltee56f2b92019-03-02 17:02:13 +010083 /* store/set the clientID as instructed by the server */
Harald Welte8e46ab62020-02-14 12:55:43 +010084 if (!srvc->clslot)
85 srvc->clslot = talloc_zero(srvc, ClientSlot_t);
86 *srvc->clslot = pdu->msg.choice.configClientIdReq.clientSlot;
87 if (!bc->bankd_conn.clslot)
88 bc->bankd_conn.clslot = talloc_zero(bc, ClientSlot_t);
89 *bc->bankd_conn.clslot = *bc->srv_conn.clslot;
Harald Welted571a3e2019-03-11 22:09:50 +010090 /* send response to server */
91 resp = rspro_gen_ConfigClientIdRes(ResultCode_ok);
92 server_conn_send_rspro(srvc, resp);
93 break;
94 case RsproPDUchoice_PR_configClientBankReq:
Harald Weltee56f2b92019-03-02 17:02:13 +010095 /* store/set the bankd ip/port as instructed by the server */
Harald Welte8e46ab62020-02-14 12:55:43 +010096 osmo_talloc_replace_string(bc, &bc->bankd_conn.server_host,
Harald Welted571a3e2019-03-11 22:09:50 +010097 rspro_IpAddr2str(&pdu->msg.choice.configClientBankReq.bankd.ip));
Harald Welte8e46ab62020-02-14 12:55:43 +010098 rspro2bank_slot(&bc->bankd_slot, &pdu->msg.choice.configClientBankReq.bankSlot);
99 bc->bankd_conn.server_port = pdu->msg.choice.configClientBankReq.bankd.port;
Harald Weltee56f2b92019-03-02 17:02:13 +0100100 /* instruct bankd FSM to connect */
Harald Welte8e46ab62020-02-14 12:55:43 +0100101 osmo_fsm_inst_dispatch(bc->bankd_conn.fi, SRVC_E_ESTABLISH, NULL);
Harald Weltee56f2b92019-03-02 17:02:13 +0100102 /* send response to server */
Harald Welted571a3e2019-03-11 22:09:50 +0100103 resp = rspro_gen_ConfigClientBankRes(ResultCode_ok);
Harald Weltea844bb02019-03-09 13:38:50 +0100104 server_conn_send_rspro(srvc, resp);
Harald Weltee56f2b92019-03-02 17:02:13 +0100105 break;
106 default:
Harald Welte8d8d4f12019-03-27 22:50:39 +0100107 LOGPFSML(srvc->fi, LOGL_ERROR, "Unknown/Unsupported RSPRO PDU type: %s\n",
108 rspro_msgt_name(pdu));
Harald Weltee56f2b92019-03-02 17:02:13 +0100109 return -1;
110 }
111
112 return 0;
113}
114
Harald Weltece638d82019-03-17 09:36:04 +0100115static void handle_sig_usr1(int signal)
116{
117 OSMO_ASSERT(signal == SIGUSR1);
Harald Welteb54a51e2019-03-31 15:57:59 +0200118 talloc_report_full(g_tall_ctx, stderr);
Harald Weltece638d82019-03-17 09:36:04 +0100119}
120
Harald Welte228af8a2019-03-08 22:20:21 +0100121static void printf_help()
122{
123 printf(
124 " -h --help Print this help message\n"
125 " -i --server-ip A.B.C.D remsim-server IP address\n"
126 " -p --server-port 13245 remsim-server TCP port\n"
127 " -i --client-id <0-65535> RSPRO ClientId of this client\n"
Harald Welte72cde102019-03-30 10:43:06 +0100128 " -n --client-slot <0-65535> RSPRO SlotNr of this client\n"
Harald Welte228af8a2019-03-08 22:20:21 +0100129 );
130}
131
132static void handle_options(int argc, char **argv)
133{
134 while (1) {
135 int option_index = 0, c;
136 static const struct option long_options[] = {
137 { "help", 0, 0, 'h' },
138 { "server-ip", 1, 0, 'i' },
139 { "server-port", 1, 0, 'p' },
140 { "client-id", 1, 0, 'c' },
Harald Welte72cde102019-03-30 10:43:06 +0100141 { "client-slot", 1, 0, 'n' },
Harald Welte228af8a2019-03-08 22:20:21 +0100142 { 0, 0, 0, 0 }
143 };
144
Harald Welte72cde102019-03-30 10:43:06 +0100145 c = getopt_long(argc, argv, "hi:p:c:n:",
Harald Welte228af8a2019-03-08 22:20:21 +0100146 long_options, &option_index);
147 if (c == -1)
148 break;
149
150 switch (c) {
151 case 'h':
152 printf_help();
153 exit(0);
154 break;
155 case 'i':
156 g_client->srv_conn.server_host = optarg;
157 break;
158 case 'p':
159 g_client->srv_conn.server_port = atoi(optarg);
160 break;
161 case 'c':
162 if (!g_client->srv_conn.clslot)
163 g_client->srv_conn.clslot = talloc_zero(g_client, ClientSlot_t);
164 g_client->srv_conn.clslot->clientId = atoi(optarg);
165 break;
Harald Welte1200c822020-02-13 20:43:27 +0100166 case 'n':
Harald Welte228af8a2019-03-08 22:20:21 +0100167 if (!g_client->srv_conn.clslot)
168 g_client->srv_conn.clslot = talloc_zero(g_client, ClientSlot_t);
169 g_client->srv_conn.clslot->slotNr = atoi(optarg);
170 break;
171 default:
172 break;
173 }
174 }
175}
176
Harald Welte2ff0ab92018-08-17 22:10:49 +0200177int main(int argc, char **argv)
178{
Harald Welted5a87292020-02-13 16:44:56 +0100179 struct rspro_server_conn *srvc, *bankdc;
Harald Weltee56f2b92019-03-02 17:02:13 +0100180 int rc;
181
Harald Welte2ff0ab92018-08-17 22:10:49 +0200182 g_tall_ctx = talloc_named_const(NULL, 0, "global");
Harald Welteb54a51e2019-03-31 15:57:59 +0200183 talloc_asn1_ctx = talloc_named_const(g_tall_ctx, 0, "asn1");
Harald Weltef7442b52019-07-18 18:54:05 +0200184 msgb_talloc_ctx_init(g_tall_ctx, 0);
Harald Welte2ff0ab92018-08-17 22:10:49 +0200185
Harald Weltec7995e72019-03-08 20:45:03 +0100186 osmo_init_logging2(g_tall_ctx, &log_info);
187
Harald Welte24173fb2018-08-24 20:37:28 +0200188 g_client = talloc_zero(g_tall_ctx, struct bankd_client);
Harald Weltee56f2b92019-03-02 17:02:13 +0100189
Harald Welte1200c822020-02-13 20:43:27 +0100190 /* create and [attempt to] establish connection to remsim-server */
Harald Weltee56f2b92019-03-02 17:02:13 +0100191 srvc = &g_client->srv_conn;
192 srvc->server_host = "localhost";
193 srvc->server_port = 9998;
194 srvc->handle_rx = srvc_handle_rx;
195 srvc->own_comp_id.type = ComponentType_remsimClient;
196 OSMO_STRLCPY_ARRAY(srvc->own_comp_id.name, "fixme-name");
197 OSMO_STRLCPY_ARRAY(srvc->own_comp_id.software, "remsim-client");
198 OSMO_STRLCPY_ARRAY(srvc->own_comp_id.sw_version, PACKAGE_VERSION);
Harald Welte228af8a2019-03-08 22:20:21 +0100199
200 handle_options(argc, argv);
201
Harald Weltece638d82019-03-17 09:36:04 +0100202 signal(SIGUSR1, handle_sig_usr1);
203
Harald Weltee56f2b92019-03-02 17:02:13 +0100204 rc = server_conn_fsm_alloc(g_client, srvc);
205 if (rc < 0) {
206 fprintf(stderr, "Unable to create Server conn FSM: %s\n", strerror(errno));
207 exit(1);
208 }
Harald Welted2192e22019-11-07 18:10:57 +0100209 osmo_fsm_inst_dispatch(srvc->fi, SRVC_E_ESTABLISH, NULL);
Harald Welte2ff0ab92018-08-17 22:10:49 +0200210
Harald Welte43ab79f2018-10-03 23:34:21 +0200211 asn_debug = 0;
Harald Welte2ff0ab92018-08-17 22:10:49 +0200212
Harald Welted5a87292020-02-13 16:44:56 +0100213 bankdc = &g_client->bankd_conn;
Harald Welte1200c822020-02-13 20:43:27 +0100214 if (srvc->clslot) {
215 bankdc->clslot = talloc_zero(g_client, ClientSlot_t);
216 *bankdc->clslot = *srvc->clslot;
217 }
218
Harald Welted5a87292020-02-13 16:44:56 +0100219 /* server_host / server_port are configured from remsim-server */
220 bankdc->handle_rx = bankd_handle_rx;
221 memcpy(&bankdc->own_comp_id, &srvc->own_comp_id, sizeof(bankdc->own_comp_id));
222 rc = server_conn_fsm_alloc(g_client, bankdc);
223 if (rc < 0) {
224 fprintf(stderr, "Unable to connect bankd conn FSM: %s\n", strerror(errno));
Harald Welte2ff0ab92018-08-17 22:10:49 +0200225 exit(1);
226 }
Harald Welte1200c822020-02-13 20:43:27 +0100227 osmo_fsm_inst_update_id(bankdc->fi, "bankd");
Harald Welte2ff0ab92018-08-17 22:10:49 +0200228
Harald Welte1200c822020-02-13 20:43:27 +0100229 client_user_main(g_client);
Harald Welte2ff0ab92018-08-17 22:10:49 +0200230}