client: Connect to server before connecting to bankd
So far we skipped the client->server connection and related
configuration transfer from server to client. Now, the server
instructs the client to which bankd ip/port to connect.
Change-Id: I76c9498089515d1a6190f3e79e143b7df3a531bd
diff --git a/src/client.h b/src/client.h
index 6918560..1917cb5 100644
--- a/src/client.h
+++ b/src/client.h
@@ -10,9 +10,10 @@
/* fsm.c */
enum bankd_conn_fsm_event {
- BDC_E_TCP_UP,
- BDC_E_TCP_DOWN,
- BDC_E_CLIENT_CONN_RES,
+ BDC_E_ESTABLISH, /* instruct BDC to (re)etablish TCP connection to bankd */
+ BDC_E_TCP_UP, /* notify BDC that TCP connection is up/connected */
+ BDC_E_TCP_DOWN, /* notify BDC that TCP connection is down/disconnected */
+ BDC_E_CLIENT_CONN_RES, /* notify BDC that ClientConnectRes has been received */
};
extern struct osmo_fsm remsim_client_bankd_fsm;
@@ -31,10 +32,12 @@
/* state */
struct ipa_client_conn *conn;
struct osmo_fsm_inst *fi;
- int (*handle_rx)(struct rspro_server_conn *conn, RsproPDU_t *pdu);
+ int (*handle_rx)(struct rspro_server_conn *conn, const RsproPDU_t *pdu);
/* our own component ID */
struct app_comp_id own_comp_id;
+ /* remote component ID */
+ struct app_comp_id peer_comp_id;
/* configuration */
char *server_host;
@@ -48,11 +51,10 @@
struct bankd_client {
/* connection to the remsim-server (control) */
- struct ipa_client_conn *srv_conn;
- struct osmo_fsm_inst *srv_fi;
+ struct rspro_server_conn srv_conn;
- /* our own component ID */
- struct app_comp_id own_comp_id;
+ /* remote component ID */
+ struct app_comp_id peer_comp_id;
/* connection to the remsim-bankd */
char *bankd_host;
diff --git a/src/remsim_client.c b/src/remsim_client.c
index 62f65f9..2f740d4 100644
--- a/src/remsim_client.c
+++ b/src/remsim_client.c
@@ -26,6 +26,8 @@
switch (pdu->msg.present) {
case RsproPDUchoice_PR_connectClientRes:
+ /* Store 'identity' of bankd to in peer_comp_id */
+ rspro_comp_id_retrieve(&bc->peer_comp_id, &pdu->msg.choice.connectClientRes.identity);
osmo_fsm_inst_dispatch(bc->bankd_fi, BDC_E_CLIENT_CONN_RES, pdu);
break;
default:
@@ -84,17 +86,62 @@
void __thread *talloc_asn1_ctx;
int asn_debug;
+/* handle incoming messages from server */
+static int srvc_handle_rx(struct rspro_server_conn *srvc, const RsproPDU_t *pdu)
+{
+ RsproPDU_t *resp;
+
+ switch (pdu->msg.present) {
+ case RsproPDUchoice_PR_connectClientRes:
+ /* Store 'identity' of server in srvc->peer_comp_id */
+ rspro_comp_id_retrieve(&srvc->peer_comp_id, &pdu->msg.choice.connectClientRes.identity);
+ osmo_fsm_inst_dispatch(srvc->fi, SRVC_E_CLIENT_CONN_RES, (void *) pdu);
+ break;
+ case RsproPDUchoice_PR_configClientReq:
+ /* store/set the clientID as instructed by the server */
+ if (!g_client->clslot)
+ g_client->clslot = talloc_zero(g_client, ClientSlot_t);
+ *g_client->clslot = pdu->msg.choice.configClientReq.clientSlot;
+ /* store/set the bankd ip/port as instructed by the server */
+ osmo_talloc_replace_string(g_client, &g_client->bankd_host,
+ rspro_IpAddr2str(&pdu->msg.choice.configClientReq.bankd.ip));
+ g_client->bankd_port = ntohs(pdu->msg.choice.configClientReq.bankd.port);
+ /* instruct bankd FSM to connect */
+ osmo_fsm_inst_dispatch(g_client->bankd_fi, BDC_E_ESTABLISH, NULL);
+ /* send response to server */
+ resp = rspro_gen_ConfigClientRes(ResultCode_ok);
+ ipa_client_conn_send_rspro(srvc->conn, resp);
+ break;
+ default:
+ fprintf(stderr, "Unknown/Unsupported RSPRO PDU type: %u\n", pdu->msg.present);
+ return -1;
+ }
+
+ return 0;
+}
+
int main(int argc, char **argv)
{
+ struct rspro_server_conn *srvc;
+ int rc;
+
g_tall_ctx = talloc_named_const(NULL, 0, "global");
g_client = talloc_zero(g_tall_ctx, struct bankd_client);
- g_client->bankd_host = "localhost";
- g_client->bankd_port = 9999;
- g_client->own_comp_id.type = ComponentType_remsimClient;
- OSMO_STRLCPY_ARRAY(g_client->own_comp_id.name, "fixme-name");
- OSMO_STRLCPY_ARRAY(g_client->own_comp_id.software, "remsim-client");
- OSMO_STRLCPY_ARRAY(g_client->own_comp_id.sw_version, PACKAGE_VERSION);
+
+ srvc = &g_client->srv_conn;
+ srvc->server_host = "localhost";
+ srvc->server_port = 9998;
+ srvc->handle_rx = srvc_handle_rx;
+ srvc->own_comp_id.type = ComponentType_remsimClient;
+ OSMO_STRLCPY_ARRAY(srvc->own_comp_id.name, "fixme-name");
+ OSMO_STRLCPY_ARRAY(srvc->own_comp_id.software, "remsim-client");
+ OSMO_STRLCPY_ARRAY(srvc->own_comp_id.sw_version, PACKAGE_VERSION);
+ rc = server_conn_fsm_alloc(g_client, srvc);
+ if (rc < 0) {
+ fprintf(stderr, "Unable to create Server conn FSM: %s\n", strerror(errno));
+ exit(1);
+ }
asn_debug = 0;
osmo_init_logging2(g_tall_ctx, &log_info);
diff --git a/src/remsim_client_fsm.c b/src/remsim_client_fsm.c
index d361659..06df4e0 100644
--- a/src/remsim_client_fsm.c
+++ b/src/remsim_client_fsm.c
@@ -57,6 +57,7 @@
};
static const struct value_string remsim_client_bankd_fsm_event_names[] = {
+ OSMO_VALUE_STRING(BDC_E_ESTABLISH),
OSMO_VALUE_STRING(BDC_E_TCP_UP),
OSMO_VALUE_STRING(BDC_E_TCP_DOWN),
OSMO_VALUE_STRING(BDC_E_CLIENT_CONN_RES),
@@ -67,33 +68,10 @@
#define T2_RECONNECT 10
-static void bdc_st_init_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
-{
- struct bankd_client *bc = (struct bankd_client *) fi->priv;
- int rc;
-
- printf("onenter\n");
- bc->bankd_conn = ipa_client_conn_create(bc, NULL, 0, bc->bankd_host, bc->bankd_port,
- bankd_updown_cb, bankd_read_cb, NULL, bc);
- if (!bc->bankd_conn) {
- fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
- exit(1);
- }
- /* Attempt to connect TCP socket */
- rc = ipa_client_conn_open(bc->bankd_conn);
- if (rc < 0) {
- fprintf(stderr, "Unable to connect: %s\n", strerror(errno));
- exit(1);
- }
-}
-
static void bdc_st_init(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
switch (event) {
- case BDC_E_TCP_UP:
- osmo_fsm_inst_state_chg(fi, BDC_ST_ESTABLISHED, T1_WAIT_CLIENT_CONN_RES, 1);
- break;
- case BDC_E_TCP_DOWN:
+ case BDC_E_ESTABLISH:
osmo_fsm_inst_state_chg(fi, BDC_ST_REESTABLISH, T2_RECONNECT, 2);
break;
default:
@@ -107,7 +85,7 @@
RsproPDU_t *pdu;
/* FIXME: Send ClientConnReq */
- pdu = rspro_gen_ConnectClientReq(&bc->own_comp_id, bc->clslot);
+ pdu = rspro_gen_ConnectClientReq(&bc->srv_conn.own_comp_id, bc->clslot);
ipa_client_conn_send_rspro(bc->bankd_conn, pdu);
}
@@ -142,6 +120,21 @@
struct bankd_client *bc = (struct bankd_client *) fi->priv;
int rc;
+ /* re-create bankd_conn */
+ if (bc->bankd_conn) {
+ LOGPFSML(fi, LOGL_INFO, "Destroying existing connection to bankd\n");
+ ipa_client_conn_destroy(bc->bankd_conn);
+ bc->bankd_conn = NULL;
+ }
+ LOGPFSML(fi, LOGL_INFO, "Creating TCP connection to bankd at %s:%u\n",
+ bc->bankd_host, bc->bankd_port);
+ bc->bankd_conn = ipa_client_conn_create(bc, NULL, 0, bc->bankd_host, bc->bankd_port,
+ bankd_updown_cb, bankd_read_cb, NULL, bc);
+ if (!bc->bankd_conn) {
+ fprintf(stderr, "Unable to create socket: %s\n", strerror(errno));
+ exit(1);
+ }
+
/* Attempt to connect TCP socket */
rc = ipa_client_conn_open(bc->bankd_conn);
if (rc < 0) {
@@ -166,14 +159,27 @@
}
}
+static void bdc_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
+{
+ switch (event) {
+ case BDC_ST_REESTABLISH:
+ osmo_fsm_inst_state_chg(fi, BDC_ST_REESTABLISH, T2_RECONNECT, 2);
+ break;
+ default:
+ OSMO_ASSERT(0);
+ }
+}
+
static int remsim_client_bankd_fsm_timer_cb(struct osmo_fsm_inst *fi)
{
switch (fi->T) {
case 2:
+ /* TCP reconnect failed: retry */
osmo_fsm_inst_state_chg(fi, BDC_ST_REESTABLISH, T2_RECONNECT, 2);
break;
case 1:
- /* FIXME: close connection and re-start */
+ /* no ClientConnectRes received: disconnect + reconnect */
+ osmo_fsm_inst_state_chg(fi, BDC_ST_REESTABLISH, T2_RECONNECT, 2);
break;
default:
OSMO_ASSERT(0);
@@ -184,8 +190,8 @@
static const struct osmo_fsm_state bankd_conn_fsm_states[] = {
[BDC_ST_INIT] = {
.name = "INIT",
- .in_event_mask = S(BDC_E_TCP_UP) | S(BDC_E_TCP_DOWN),
- .out_state_mask = S(BDC_ST_ESTABLISHED) | S(BDC_ST_REESTABLISH),
+ .in_event_mask = 0, /* S(BDC_E_ESTABLISH) via allstate */
+ .out_state_mask = S(BDC_ST_REESTABLISH),
.action = bdc_st_init,
},
[BDC_ST_ESTABLISHED] = {
@@ -214,6 +220,8 @@
.name = "BANKD_CONN",
.states = bankd_conn_fsm_states,
.num_states = ARRAY_SIZE(bankd_conn_fsm_states),
+ .allstate_event_mask = S(BDC_E_ESTABLISH),
+ .allstate_action = bdc_allstate_action,
.timer_cb = remsim_client_bankd_fsm_timer_cb,
.log_subsys = DMAIN,
.event_names = remsim_client_bankd_fsm_event_names,
@@ -228,8 +236,6 @@
return -1;
bc->bankd_fi = fi;
- /* onenter of the initial state is not automatically executed by osmo_fsm :( */
- bdc_st_init_onenter(fi, 0);
return 0;
}
diff --git a/src/simtrace2-remsim_client.c b/src/simtrace2-remsim_client.c
index 6d31d32..79da419 100644
--- a/src/simtrace2-remsim_client.c
+++ b/src/simtrace2-remsim_client.c
@@ -539,6 +539,8 @@
switch (pdu->msg.present) {
case RsproPDUchoice_PR_connectClientRes:
+ /* Store 'identity' of bankd to in peer_comp_id */
+ rspro_comp_id_retrieve(&bc->peer_comp_id, &pdu->msg.choice.connectClientRes.identity);
osmo_fsm_inst_dispatch(bc->bankd_fi, BDC_E_CLIENT_CONN_RES, pdu);
break;
case RsproPDUchoice_PR_tpduCardToModem: // APDU response from card received
@@ -582,6 +584,41 @@
return -1;
}
+/* handle incoming messages from server */
+static int srvc_handle_rx(struct rspro_server_conn *srvc, const RsproPDU_t *pdu)
+{
+ RsproPDU_t *resp;
+
+ switch (pdu->msg.present) {
+ case RsproPDUchoice_PR_connectClientRes:
+ /* Store 'identity' of server in srvc->peer_comp_id */
+ rspro_comp_id_retrieve(&srvc->peer_comp_id, &pdu->msg.choice.connectClientRes.identity);
+ osmo_fsm_inst_dispatch(srvc->fi, SRVC_E_CLIENT_CONN_RES, (void *) pdu);
+ break;
+ case RsproPDUchoice_PR_configClientReq:
+ /* store/set the clientID as instructed by the server */
+ if (!g_client->clslot)
+ g_client->clslot = talloc_zero(g_client, ClientSlot_t);
+ *g_client->clslot = pdu->msg.choice.configClientReq.clientSlot;
+ /* store/set the bankd ip/port as instructed by the server */
+ osmo_talloc_replace_string(g_client, &g_client->bankd_host,
+ rspro_IpAddr2str(&pdu->msg.choice.configClientReq.bankd.ip));
+ g_client->bankd_port = ntohs(pdu->msg.choice.configClientReq.bankd.port);
+ /* instruct bankd FSM to connect */
+ osmo_fsm_inst_dispatch(g_client->bankd_fi, BDC_E_ESTABLISH, NULL);
+ /* send response to server */
+ resp = rspro_gen_ConfigClientRes(ResultCode_ok);
+ ipa_client_conn_send_rspro(srvc->conn, resp);
+ break;
+ default:
+ fprintf(stderr, "Unknown/Unsupported RSPRO PDU type: %u\n", pdu->msg.present);
+ return -1;
+ }
+
+ return 0;
+}
+
+
static const struct log_info_cat default_categories[] = {
[DMAIN] = {
.name = "DMAIN",
@@ -604,10 +641,8 @@
static void print_help(void)
{
- printf( "\t-d\t--bankd-host HOST\n"
+ printf( "\t-s\t--server-host HOST\n"
"\t-p\t--bankd-port PORT\n"
- "\t-c\t--client-id REMSIM_CLIENT_ID\n"
- "\t-s\t--slot-nr REMSIM_SLOT_NUMBER\n"
"\t-h\t--help\n"
"\t-i\t--gsmtap-ip\tA.B.C.D\n"
"\t-k\t--keep-running\n"
@@ -624,10 +659,8 @@
}
static const struct option opts[] = {
- { "bankd-host", 1, 0, 'b' },
- { "bankd-port", 1, 0, 'p' },
- { "client-id", 1, 0, 'c' },
- { "slot-nr", 1, 0, 's' },
+ { "server-host", 1, 0, 's' },
+ { "server-port", 1, 0, 'p' },
{ "gsmtap-ip", 1, 0, 'i' },
{ "help", 0, 0, 'h' },
{ "keep-running", 0, 0, 'k' },
@@ -644,16 +677,16 @@
int main(int argc, char **argv)
{
+ struct rspro_server_conn *srvc;
struct st_transport *transp = ci->slot->transp;
char *gsmtap_host = "127.0.0.1";
int rc;
int c, ret = 1;
int keep_running = 0;
- int bankd_port = 9999;
- int client_id = -1, slot_nr = -1;
+ int server_port = 9999;
int if_num = 0, vendor_id = -1, product_id = -1;
int config_id = -1, altsetting = 0, addr = -1;
- char *bankd_host = "127.0.0.1";
+ char *server_host = "127.0.0.1";
char *path = NULL;
uint8_t atr_data[33] = { 0x3B, 0x00 }; // the shortest simplest ATR possible
uint8_t atr_len = 2;
@@ -663,21 +696,15 @@
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "b:p:c:s:hi:V:P:C:I:S:A:H:a:k", opts, &option_index);
+ c = getopt_long(argc, argv, "s:p:hi:V:P:C:I:S:A:H:a:k", opts, &option_index);
if (c == -1)
break;
switch (c) {
- case 'b':
- bankd_host = optarg;
+ case 's':
+ server_host = optarg;
break;
case 'p':
- bankd_port = atoi(optarg);
- break;
- case 'c':
- client_id = atoi(optarg);
- break;
- case 's':
- slot_nr = atoi(optarg);
+ server_port = atoi(optarg);
break;
case 'h':
print_help();
@@ -726,11 +753,6 @@
goto do_exit;
}
- if (client_id < 0 || slot_nr < 0) {
- fprintf(stderr, "You have to specify the remote SIM client ID and slot number\n");
- goto do_exit;
- }
-
rc = libusb_init(NULL);
if (rc < 0) {
fprintf(stderr, "libusb initialization failed\n");
@@ -750,13 +772,20 @@
g_tall_ctx = talloc_named_const(NULL, 0, "global");
g_client = talloc_zero(g_tall_ctx, struct bankd_client);
- g_client->bankd_host = bankd_host;
- g_client->bankd_port = bankd_port;
- g_client->own_comp_id.type = ComponentType_remsimClient;
- g_client->clslot = &(ClientSlot_t){ .clientId = client_id, .slotNr = slot_nr };
- OSMO_STRLCPY_ARRAY(g_client->own_comp_id.name, "simtrace2-remsim-client");
- OSMO_STRLCPY_ARRAY(g_client->own_comp_id.software, "remsim-client");
- OSMO_STRLCPY_ARRAY(g_client->own_comp_id.sw_version, PACKAGE_VERSION);
+
+ srvc = &g_client->srv_conn;
+ srvc->server_host = server_host;
+ srvc->server_port = server_port;
+ srvc->handle_rx = srvc_handle_rx;
+ srvc->own_comp_id.type = ComponentType_remsimClient;
+ OSMO_STRLCPY_ARRAY(srvc->own_comp_id.name, "simtrace2-remsim-client");
+ OSMO_STRLCPY_ARRAY(srvc->own_comp_id.software, "remsim-client");
+ OSMO_STRLCPY_ARRAY(srvc->own_comp_id.sw_version, PACKAGE_VERSION);
+ rc = server_conn_fsm_alloc(g_client, srvc);
+ if (rc < 0) {
+ fprintf(stderr, "Unable to create Server conn FSM: %s\n", strerror(errno));
+ exit(1);
+ }
asn_debug = 0;
osmo_init_logging2(g_tall_ctx, &log_info);