libgtp: introduce cb_recovery() callback

The cb_recovery() callback enables the user application to detect
a change in the restart counter and thus start the appropriate
recovery procedures.
diff --git a/gtp/gtp.c b/gtp/gtp.c
index 133e2aa..922fcb7 100644
--- a/gtp/gtp.c
+++ b/gtp/gtp.c
@@ -160,6 +160,13 @@
   return 0;
 }
 
+int gtp_set_cb_recovery(struct gsn_t *gsn,
+		        int (*cb) (struct sockaddr_in *peer,
+				   uint8_t recovery)) {
+  gsn->cb_recovery = cb;
+  return 0;
+}
+
 extern int gtp_set_cb_data_ind(struct gsn_t *gsn,
 			   int (*cb_data_ind) (struct pdp_t* pdp,
 					   void* pack,
@@ -932,6 +939,8 @@
   /* Instead we return the recovery number in the callback function */
   if (gsn->cb_conf) gsn->cb_conf(type, recovery, NULL, cbp);
 
+  if (gsn->cb_recovery) gsn->cb_recovery(peer, recovery);
+
   return 0;
 }
 
@@ -1343,7 +1352,7 @@
   
   /* Recovery (optional) */
   if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
-    /* TODO: Handle received recovery IE */
+    if (gsn->cb_recovery) gsn->cb_recovery(peer, recovery);
   }
   
   /* Selection mode (conditional) */
@@ -1619,7 +1628,7 @@
 
   /* Extract recovery (optional) */
   if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
-    /* TODO: Handle received recovery IE */
+    if (gsn->cb_recovery) gsn->cb_recovery(peer, recovery);
   }
 
   /* Extract protocol configuration options (optional) */
@@ -2001,7 +2010,7 @@
 
   /* Recovery (optional) */
   if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
-    /* TODO: Handle received recovery IE */
+    if (gsn->cb_recovery) gsn->cb_recovery(peer, recovery);
   }
 
   if (version == 0) {
@@ -2166,7 +2175,7 @@
 
   /* Extract recovery (optional) */
   if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
-    /* TODO: Handle received recovery IE */
+    if (gsn->cb_recovery) gsn->cb_recovery(peer, recovery);
   }
 
   /* Check all conditional information elements */
diff --git a/gtp/gtp.h b/gtp/gtp.h
index 7b5083b..fb4cc3d 100644
--- a/gtp/gtp.h
+++ b/gtp/gtp.h
@@ -260,6 +260,7 @@
   int (*cb_extheader_ind) (struct sockaddr_in *peer);
   int (*cb_conf) (int type, int cause, struct pdp_t *pdp, void* cbp);
   int (*cb_data_ind) (struct pdp_t* pdp, void* pack, unsigned len);
+  int (*cb_recovery) (struct sockaddr_in *peer, uint8_t recovery);
 
   /* Counters */
   
@@ -343,6 +344,8 @@
 extern int gtp_set_cb_conf(struct gsn_t *gsn,
              int (*cb) (int type, int cause, struct pdp_t* pdp, void *cbp));
 
+int gtp_set_cb_recovery(struct gsn_t *gsn,
+		        int (*cb) (struct sockaddr_in *peer, uint8_t recovery));
 
 /* Internal functions (not part of the API */