mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
				synced 2025-11-03 21:43:32 +00:00 
			
		
		
		
	gprs: Send PING and eventually reconnect
Currently, the reconnect mechanism relies on gsup_client_updown_cb which in turn gets called based on the OS' view of connection state. This patch adds a timer based PING mechanism that regularly sends PING messages and forces a reconnect if a PONG message won't be received until the next PING message is scheduled. The current ping interval is 20s. Sponsored-by: On-Waves ehf Conflicts: openbsc/src/gprs/gprs_gsup_client.c [hfreyther: Conflicts due the potential memleak fix by me. Removed another TODO from the code as we stop the ping/pong timer]
This commit is contained in:
		
				
					committed by
					
						
						Holger Hans Peter Freyther
					
				
			
			
				
	
			
			
			
						parent
						
							e154d8bdd4
						
					
				
				
					commit
					03b4630348
				
			@@ -24,6 +24,7 @@
 | 
			
		||||
#include <osmocom/core/timer.h>
 | 
			
		||||
 | 
			
		||||
#define GPRS_GSUP_RECONNECT_INTERVAL 10
 | 
			
		||||
#define GPRS_GSUP_PING_INTERVAL 20
 | 
			
		||||
 | 
			
		||||
struct msgb;
 | 
			
		||||
struct ipa_client_conn;
 | 
			
		||||
@@ -37,8 +38,10 @@ struct gprs_gsup_client {
 | 
			
		||||
	gprs_gsup_read_cb_t	read_cb;
 | 
			
		||||
	void			*data;
 | 
			
		||||
 | 
			
		||||
	struct osmo_timer_list	ping_timer;
 | 
			
		||||
	struct osmo_timer_list	connect_timer;
 | 
			
		||||
	int			is_connected;
 | 
			
		||||
	int			got_ipa_pong;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct gprs_gsup_client *gprs_gsup_client_create(const char *ip_addr,
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,18 @@
 | 
			
		||||
 | 
			
		||||
extern void *tall_bsc_ctx;
 | 
			
		||||
 | 
			
		||||
static void start_test_procedure(struct gprs_gsup_client *gsupc);
 | 
			
		||||
 | 
			
		||||
static void gsup_client_send_ping(struct gprs_gsup_client *gsupc)
 | 
			
		||||
{
 | 
			
		||||
	struct msgb *msg = gprs_gsup_msgb_alloc();
 | 
			
		||||
 | 
			
		||||
	msg->l2h = msgb_put(msg, 1);
 | 
			
		||||
	msg->l2h[0] = IPAC_MSGT_PING;
 | 
			
		||||
	ipa_msg_push_header(msg, IPAC_PROTO_IPACCESS);
 | 
			
		||||
	ipa_client_conn_send(gsupc->link, msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int gsup_client_connect(struct gprs_gsup_client *gsupc)
 | 
			
		||||
{
 | 
			
		||||
	int rc;
 | 
			
		||||
@@ -46,6 +58,12 @@ static int gsup_client_connect(struct gprs_gsup_client *gsupc)
 | 
			
		||||
		osmo_timer_del(&gsupc->connect_timer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (osmo_timer_pending(&gsupc->ping_timer)) {
 | 
			
		||||
		LOGP(DLINP, LOGL_DEBUG,
 | 
			
		||||
		     "GSUP connect: ping timer already running\n");
 | 
			
		||||
		osmo_timer_del(&gsupc->ping_timer);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ipa_client_conn_clear_queue(gsupc->link) > 0)
 | 
			
		||||
		LOGP(DLINP, LOGL_DEBUG, "GSUP connect: discarded stored messages\n");
 | 
			
		||||
 | 
			
		||||
@@ -83,17 +101,17 @@ static void gsup_client_updown_cb(struct ipa_client_conn *link, int up)
 | 
			
		||||
{
 | 
			
		||||
	struct gprs_gsup_client *gsupc = link->data;
 | 
			
		||||
 | 
			
		||||
	LOGP(DGPRS, LOGL_NOTICE, "GSUP link to %s:%d %s\n",
 | 
			
		||||
	LOGP(DGPRS, LOGL_INFO, "GSUP link to %s:%d %s\n",
 | 
			
		||||
		     link->addr, link->port, up ? "UP" : "DOWN");
 | 
			
		||||
 | 
			
		||||
	gsupc->is_connected = up;
 | 
			
		||||
 | 
			
		||||
	if (up) {
 | 
			
		||||
		/* TODO: Start ping procedure */
 | 
			
		||||
		start_test_procedure(gsupc);
 | 
			
		||||
 | 
			
		||||
		osmo_timer_del(&gsupc->connect_timer);
 | 
			
		||||
	} else {
 | 
			
		||||
		/* TODO: Stop ping procedure */
 | 
			
		||||
		osmo_timer_del(&gsupc->ping_timer);
 | 
			
		||||
 | 
			
		||||
		osmo_timer_schedule(&gsupc->connect_timer,
 | 
			
		||||
				    GPRS_GSUP_RECONNECT_INTERVAL, 0);
 | 
			
		||||
@@ -125,7 +143,12 @@ static int gsup_client_read_cb(struct ipa_client_conn *link, struct msgb *msg)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (rc == 1) {
 | 
			
		||||
		uint8_t msg_type = *(msg->l2h);
 | 
			
		||||
		/* CCM message */
 | 
			
		||||
		if (msg_type == IPAC_MSGT_PONG) {
 | 
			
		||||
			LOGP(DGPRS, LOGL_DEBUG, "GSUP receiving PONG\n");
 | 
			
		||||
			gsupc->got_ipa_pong = 1;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		msgb_free(msg);
 | 
			
		||||
		return 0;
 | 
			
		||||
@@ -155,6 +178,37 @@ invalid:
 | 
			
		||||
	return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ping_timer_cb(void *gsupc_)
 | 
			
		||||
{
 | 
			
		||||
	struct gprs_gsup_client *gsupc = gsupc_;
 | 
			
		||||
 | 
			
		||||
	LOGP(DGPRS, LOGL_INFO, "GSUP ping callback (%s, %s PONG)\n",
 | 
			
		||||
	     gsupc->is_connected ? "connected" : "not connected",
 | 
			
		||||
	     gsupc->got_ipa_pong ? "got" : "didn't get");
 | 
			
		||||
 | 
			
		||||
	if (gsupc->got_ipa_pong) {
 | 
			
		||||
		start_test_procedure(gsupc);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	LOGP(DGPRS, LOGL_NOTICE, "GSUP ping timed out, reconnecting\n");
 | 
			
		||||
	ipa_client_conn_close(gsupc->link);
 | 
			
		||||
	gsupc->is_connected = 0;
 | 
			
		||||
 | 
			
		||||
	gsup_client_connect(gsupc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void start_test_procedure(struct gprs_gsup_client *gsupc)
 | 
			
		||||
{
 | 
			
		||||
	gsupc->ping_timer.data = gsupc;
 | 
			
		||||
	gsupc->ping_timer.cb = &ping_timer_cb;
 | 
			
		||||
 | 
			
		||||
	gsupc->got_ipa_pong = 0;
 | 
			
		||||
	osmo_timer_schedule(&gsupc->ping_timer, GPRS_GSUP_PING_INTERVAL, 0);
 | 
			
		||||
	LOGP(DGPRS, LOGL_DEBUG, "GSUP sending PING\n");
 | 
			
		||||
	gsup_client_send_ping(gsupc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct gprs_gsup_client *gprs_gsup_client_create(const char *ip_addr,
 | 
			
		||||
						 unsigned int tcp_port,
 | 
			
		||||
						 gprs_gsup_read_cb_t read_cb)
 | 
			
		||||
@@ -196,6 +250,7 @@ failed:
 | 
			
		||||
void gprs_gsup_client_destroy(struct gprs_gsup_client *gsupc)
 | 
			
		||||
{
 | 
			
		||||
	osmo_timer_del(&gsupc->connect_timer);
 | 
			
		||||
	osmo_timer_del(&gsupc->ping_timer);
 | 
			
		||||
 | 
			
		||||
	if (gsupc->link) {
 | 
			
		||||
		ipa_client_conn_close(gsupc->link);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user