From 53e146608d6933f0b1cf35f79f2abac1bbcb0f28 Mon Sep 17 00:00:00 2001
From: Lionel Gauthier <lionel.gauthier@eurecom.fr>
Date: Fri, 17 Jan 2014 13:08:12 +0000
Subject: [PATCH] git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4902
 818b1a75-f10b-46b9-bf7c-635c3b92a50f

---
 .../LTE_RAL_UE/MIH-USER/lte_test_user/Jamfile |   21 +-
 .../MIH-USER/lte_test_user/README.txt         |   11 +
 .../MIH-USER/lte_test_user/lte_user.conf      |    6 +-
 .../MIH-USER/lte_test_user/ue_lte_user.conf   |   42 +
 .../MIH-USER/lte_test_user/ue_lte_user.cpp    | 1400 +++++++++++++++++
 5 files changed, 1468 insertions(+), 12 deletions(-)
 create mode 100755 openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/README.txt
 create mode 100755 openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.conf
 create mode 100755 openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.cpp

diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/Jamfile b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/Jamfile
index 1ab5facb05..36011a7356 100755
--- a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/Jamfile
+++ b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/Jamfile
@@ -16,18 +16,19 @@
 # This software is distributed without any warranty.
 #===============================================================================
 
-project lte_user
+
+install install
+	: ue_lte_user
+	  ue_lte_user.conf
+	: <location>../../dist
 	;
 
-exe lte_user
-	: mih_usr.cpp
-	  ../../lib/odtone//odtone_base
-	  ../../lib/odtone/mih//odtone_mih
-	  ../../lib/odtone/sap//odtone_sap
+project ue_lte_user
 	;
 
-install install
-	: lte_user
-	  lte_user.conf
-	: <location>../../dist
+exe ue_lte_user
+	: ue_lte_user.cpp
+	  ../../lib/odtone//odtone
+	  /boost//program_options
 	;
+
diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/README.txt b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/README.txt
new file mode 100755
index 0000000000..2e951b5bec
--- /dev/null
+++ b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/README.txt
@@ -0,0 +1,11 @@
+FILES TO BE USED:
+Jamfile
+ue_lte_user.conf
+ue_lte_user.cpp
+README.txt
+
+FILES OBSOLETES:
+lte_user.conf
+mih_usr.cpp
+
+
diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/lte_user.conf b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/lte_user.conf
index 4e14bcf4a9..ab40db1085 100755
--- a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/lte_user.conf
+++ b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/lte_user.conf
@@ -20,7 +20,7 @@
 ## User id
 ##
 [user]
-id = user
+id = user_ue
 
 ##
 ## Commands supported by the MIH-User
@@ -31,10 +31,12 @@ commands = mih_link_get_parameters, mih_link_configure_thresholds, mih_link_acti
 ## Port used for communication with MIHF
 ##
 [conf]
-port = 1234
+port = 1235
 
 ##
 ## MIHF configuration. For the default demonstration leave as is.
 ##
 [mihf]
 local_port = 1025
+
+
diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.conf b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.conf
new file mode 100755
index 0000000000..ab40db1085
--- /dev/null
+++ b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.conf
@@ -0,0 +1,42 @@
+#===============================================================================
+# Brief   : MIH-User configuration file
+# Authors : Carlos Guimaraes <cguimaraes@av.it.pt>
+#           Bruno Santos     <bsantos@av.it.pt>
+#-------------------------------------------------------------------------------
+# ODTONE - Open Dot Twenty One
+#
+# Copyright (C) 2009-2012 Universidade Aveiro
+# Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro
+#
+# This software is distributed under a license. The full license
+# agreement can be found in the file LICENSE in this distribution.
+# This software may not be copied, modified, sold or distributed
+# other than expressed in the named license agreement.
+#
+# This software is distributed without any warranty.
+#===============================================================================
+
+##
+## User id
+##
+[user]
+id = user_ue
+
+##
+## Commands supported by the MIH-User
+##
+commands = mih_link_get_parameters, mih_link_configure_thresholds, mih_link_actions, mih_net_ho_candidate_query, mih_net_ho_commit, mih_n2n_ho_query_resources, mih_n2n_ho_commit, mih_n2n_ho_complete, mih_mn_ho_candidate_query, mih_mn_ho_commit, mih_mn_ho_complete
+
+##
+## Port used for communication with MIHF
+##
+[conf]
+port = 1235
+
+##
+## MIHF configuration. For the default demonstration leave as is.
+##
+[mihf]
+local_port = 1025
+
+
diff --git a/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.cpp b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.cpp
new file mode 100755
index 0000000000..807239f299
--- /dev/null
+++ b/openair3/RAL-LTE/LTE_RAL_UE/MIH-USER/lte_test_user/ue_lte_user.cpp
@@ -0,0 +1,1400 @@
+//==============================================================================
+// Brief   : MIH-User
+// Authors : Bruno Santos <bsantos@av.it.pt>
+//------------------------------------------------------------------------------
+// ODTONE - Open Dot Twenty One
+//
+// Copyright (C) 2009-2012 Universidade Aveiro
+// Copyright (C) 2009-2012 Instituto de Telecomunicações - Pólo Aveiro
+//
+// This software is distributed under a license. The full license
+// agreement can be found in the file LICENSE in this distribution.
+// This software may not be copied, modified, sold or distributed
+// other than expressed in the named license agreement.
+//
+// This software is distributed without any warranty.
+//==============================================================================
+
+#include <odtone/base.hpp>
+#include <odtone/debug.hpp>
+#include <odtone/logger.hpp>
+#include <odtone/mih/request.hpp>
+#include <odtone/mih/response.hpp>
+#include <odtone/mih/indication.hpp>
+#include <odtone/mih/confirm.hpp>
+#include <odtone/mih/tlv_types.hpp>
+#include <odtone/sap/user.hpp>
+
+#include <boost/utility.hpp>
+#include <boost/bind.hpp>
+#include <boost/tokenizer.hpp>
+#include <boost/foreach.hpp>
+#include <boost/format.hpp>
+
+#include <iostream>
+#include <map>
+#include <time.h>
+
+///////////////////////////////////////////////////////////////////////////////
+
+// Definition of the scenario to execute
+#define NB_OF_RESOURCES		4	// Should not exceed mih_user::_max_link_action_requests
+//#define SCENARIO_1	// Sequentially activate and deactivate each resource
+//#define SCENARIO_2	// Activate all resources, then deactivate all resources
+#define NUM_PARM_REPORT 10
+
+///////////////////////////////////////////////////////////////////////////////
+// The scenario coded in this MIH-USER demo is the following
+//  +--------+                                             +-----+                                             +---------+
+//  |MIH_USER|                                             |MIH-F|                                             |LINK_SAP |
+//  +---+----+                                             +--+--+                                             +----+----+
+//      |                                                     |                                                     |
+//     ...          (start of MIH-F here)                    ...                                                   ...
+//      |                                                     |---------- Link_Capability_Discover.request --------X|
+//     ...          (start of LINK_SAP here)                 ...                                                   ...
+//      |                                                     |<--------- Link_Register.indication -----------------|
+//      |                                                     |---------- Link_Capability_Discover.request -------->|
+//      |                                                     |<--------- Link_Capability_Discover.confirm ---------|
+//      |                                                     |                                                     |
+//     ...          (start of MIH USER here)                 ...                                                   ...
+//      |---------- MIH_User_Register.indication ------------>| (supported_commands)                                |
+//      |                                                     |                                                     |
+//      |---------- MIH_Capability_Discover.request --------->|                                                     |
+//      |<--------- MIH_Capability_Discover.confirm ----------|                                                     |
+//      |                                                     |                                                     |
+//      |---------- MIH_Event_Subscribe.request ------------->|---------- Link_Event_Subscribe.request ------------>|
+//      |<--------- MIH_Event_Subscribe.confirm --------------|<--------- Link_Event_Subscribe.confirm -------------|
+//      |                                                     |                                                     |
+//      |---------- MIH_Link_Actions.request ---------------->|---------- Link_Actions.request -------------------->|
+//      |            (POWER UP + SCAN)                        |             (POWER UP + SCAN)                       |
+//     ...                                                   ...                                                   ...
+//      |                                                     |                                                     |
+//      |<--------- Link_Detected.indication -----------------|<--------- Link_Detected.indication -----------------|
+//      |                                                     |                                                     |
+//      |<--------- Link_Up.indication -----------------------|<--------- Link_Up.indication -----------------------|
+//      |                                                     |    RRC Connection Reestablishment notification)     |
+//      |                                                     |                                                     |
+//      |---------- MIH_Link_Configure_Thresholds.request --->|---------- Link_Configure_Thresholds.request ------->|
+//      |                                                     |                                                     |
+//      |<--------- Link_Up.indication -----------------------|<--------- Link_Up.indication -----------------------|
+//      |                                                     |     (RRC Connection reconfiguration notification)   |
+//      |<--------- MIH_Link_Configure_Thresholds.confirm ----|<--------- Link_Configure_Thresholds.confirm --------|
+//      |                                                     |                                                     |
+//      |<--------- MIH_Link_Parameters_Report.indication ----|<--------- MIH_Link_Parameters_Report.indication ----|
+//     ...                                                   ...                                                   ...
+//      |<--------- MIH_Link_Actions.confirm -----------------|<--------- Link_Actions.confirm ---------------------|
+//      |                (Success)                            |                                                     |
+//      |<--------- MIH_Link_Parameters_Report.indication ----|<--------- MIH_Link_Parameters_Report.indication ----|
+//     ...                                                   ...                                                   ...
+//      |<--------- MIH_Link_Parameters_Report.indication ----|<--------- MIH_Link_Parameters_Report.indication ----|
+//     ...                                                   ...                                                   ...
+//      |<--------- MIH_Link_Parameters_Report.indication ----|<--------- MIH_Link_Parameters_Report.indication ----|
+//     ...                                                   ...                                                   ...
+//     etc                                                   etc                                                   etc
+
+///////////////////////////////////////////////////////////////////////////////
+
+static const char* const kConf_MIH_Commands = "user.commands";
+
+///////////////////////////////////////////////////////////////////////////////
+
+namespace po = boost::program_options;
+
+using odtone::uint;
+using odtone::ushort;
+using odtone::sint8;
+
+odtone::logger log_("[mih_usr]", std::cout);
+
+///////////////////////////////////////////////////////////////////////////////
+
+//-----------------------------------------------------------------------------
+void __trim(odtone::mih::octet_string &str, const char chr)
+//-----------------------------------------------------------------------------
+{
+    str.erase(std::remove(str.begin(), str.end(), chr), str.end());
+}
+//-----------------------------------------------------------------------------
+template <class T> std::string StringOf(T object) {
+//-----------------------------------------------------------------------------
+    std::ostringstream os;
+    os << object;
+    return(os.str());
+}
+//-----------------------------------------------------------------------------
+std::string getTimeStamp4Log()
+//-----------------------------------------------------------------------------
+{
+    std::stringstream ss (std::stringstream::in | std::stringstream::out);
+    struct timespec time_spec;
+    unsigned int time_now_micros;
+    unsigned int time_now_s;
+    clock_gettime (CLOCK_REALTIME, &time_spec);
+    time_now_s      = (unsigned int) time_spec.tv_sec % 3600;
+    time_now_micros = (unsigned int) time_spec.tv_nsec/1000;
+    ss << time_now_s << ':' << time_now_micros;
+    return ss.str();
+}
+//-----------------------------------------------------------------------------
+std::string status2string(odtone::mih::status statusP){
+//-----------------------------------------------------------------------------
+    switch (statusP.get()) {
+        case odtone::mih::status_success:                 return "SUCCESS";break;
+        case odtone::mih::status_failure:                 return "UNSPECIFIED_FAILURE";break;
+        case odtone::mih::status_rejected:                return "REJECTED";break;
+        case odtone::mih::status_authorization_failure:   return "AUTHORIZATION_FAILURE";break;
+        case odtone::mih::status_network_error:           return "NETWORK_ERROR";break;
+        default:                                          return "UNKNOWN";
+    }
+}
+//-----------------------------------------------------------------------------
+std::string link_down_reason2string(odtone::mih::link_dn_reason reasonP){
+//-----------------------------------------------------------------------------
+    switch (reasonP.get()) {
+        case odtone::mih::link_dn_reason_explicit_disconnect:       return "DN_REASON_EXPLICIT_DISCONNECT";break;
+        case odtone::mih::link_dn_reason_packet_timeout:            return "DN_REASON_PACKET_TIMEOUT";break;
+        case odtone::mih::link_dn_reason_no_resource:               return "DN_REASON_NO_RESOURCE";break;
+        case odtone::mih::link_dn_reason_no_broadcast:              return "DN_REASON_NO_BROADCAST";break;
+        case odtone::mih::link_dn_reason_authentication_failure:    return "DN_REASON_AUTHENTICATION_FAILURE";break;
+        case odtone::mih::link_dn_reason_billing_failure:           return "DN_REASON_BILLING_FAILURE";break;
+        default:                                                    return "DN_REASON_UNKNOWN";
+    }
+}
+//-----------------------------------------------------------------------------
+std::string link_going_down_reason2string(odtone::mih::link_gd_reason reasonP){
+//-----------------------------------------------------------------------------
+    switch (reasonP.get()) {
+        case odtone::mih::link_gd_reason_explicit_disconnect:       return "GD_REASON_EXPLICIT_DISCONNECT";break;
+        case odtone::mih::link_gd_reason_link_parameter_degrading:  return "GD_REASON_PARAMETER_DEGRADING";break;
+        case odtone::mih::link_gd_reason_low_power:                 return "GD_REASON_LOW_POWER";break;
+        case odtone::mih::link_gd_reason_no_resource:               return "GD_REASON_NO_RESOURCE";break;
+        default:                                                    return "GD_REASON_UNKNOWN";
+    }
+}
+//-----------------------------------------------------------------------------
+std::string evt2string(odtone::mih::mih_evt_list evtP){
+//-----------------------------------------------------------------------------
+    std::string s=std::string(" ");
+    if(evtP.get(odtone::mih::mih_evt_link_detected))            s += "DETECTED ";
+    if(evtP.get(odtone::mih::mih_evt_link_up))                  s += "UP ";
+    if(evtP.get(odtone::mih::mih_evt_link_down))                s += "DOWN ";
+    if(evtP.get(odtone::mih::mih_evt_link_parameters_report))   s += "PARAMETERS_REPORT ";
+    if(evtP.get(odtone::mih::mih_evt_link_going_down))          s += "GOING_DOWN ";
+    if(evtP.get(odtone::mih::mih_evt_link_handover_imminent))   s += "HANDOVER_IMMINENT ";
+    if(evtP.get(odtone::mih::mih_evt_link_handover_complete))   s += "HANDOVER_COMPLETE ";
+    if(evtP.get(odtone::mih::mih_evt_link_pdu_transmit_status)) s += "PDU_TRANSMIT_STATUS ";
+    return s;
+}
+//-----------------------------------------------------------------------------
+std::string cmd2string(odtone::mih::mih_cmd_list cmdP){
+//-----------------------------------------------------------------------------
+    std::string s=std::string(" ");
+    if(cmdP.get(odtone::mih::mih_cmd_link_get_parameters))       s += "Link_Get_Parameters ";
+    if(cmdP.get(odtone::mih::mih_cmd_link_configure_thresholds)) s += "Link_Configure_Thresholds ";
+    if(cmdP.get(odtone::mih::mih_cmd_link_actions))              s += "Link_Actions ";
+    if(cmdP.get(odtone::mih::mih_cmd_net_ho_candidate_query))    s += "Net_HO_Candidate_Query ";
+    if(cmdP.get(odtone::mih::mih_cmd_net_ho_commit))             s += "Net_HO_Commit ";
+    if(cmdP.get(odtone::mih::mih_cmd_n2n_ho_query_resources))    s += "N2N_HO_Query_Resources ";
+    if(cmdP.get(odtone::mih::mih_cmd_n2n_ho_commit))             s += "N2N_HO_Commit ";
+    if(cmdP.get(odtone::mih::mih_cmd_n2n_ho_complete))           s += "N2N_HO_Complete ";
+    if(cmdP.get(odtone::mih::mih_cmd_mn_ho_candidate_query))     s += "MN_HO_Candidate_Query ";
+    if(cmdP.get(odtone::mih::mih_cmd_mn_ho_commit))              s += "MN_HO_Commit ";
+    if(cmdP.get(odtone::mih::mih_cmd_mn_ho_complete))            s += "MN_HO_Complete ";
+    return s;
+}
+//-----------------------------------------------------------------------------
+std::string link_type2string(const odtone::mih::link_type& lt)
+//-----------------------------------------------------------------------------
+{
+    switch (lt.get()) {
+	case odtone::mih::link_type_gsm:            return "GSM";            break;
+	case odtone::mih::link_type_gprs:           return "GPRS";           break;
+	case odtone::mih::link_type_edge:           return "EDGE";           break;
+	case odtone::mih::link_type_ethernet:       return "Ethernet";       break;
+	case odtone::mih::link_type_wireless_other: return "Other";          break;
+	case odtone::mih::link_type_802_11:         return "IEEE 802.11";    break;
+	case odtone::mih::link_type_cdma2000:       return "CDMA-2000";      break;
+	case odtone::mih::link_type_umts:           return "UMTS";           break;
+	case odtone::mih::link_type_cdma2000_hrpd:  return "CDMA-2000-HRPD"; break;
+	case odtone::mih::link_type_lte:            return "LTE";            break;
+	case odtone::mih::link_type_802_16:         return "IEEE 802.16";    break;
+	case odtone::mih::link_type_802_20:         return "IEEE 802.20";    break;
+	case odtone::mih::link_type_802_22:         return "IEEE 802.22";    break;
+	default:                                                             break;
+    }
+    return "Unknown link type";
+}
+//-----------------------------------------------------------------------------
+std::string link_addr2string(const odtone::mih::link_addr *addr)
+//-----------------------------------------------------------------------------
+{
+    if (const odtone::mih::mac_addr                 *la = boost::get<odtone::mih::mac_addr>(addr)) {
+      return la->address();
+    }
+    else if  (const odtone::mih::l2_3gpp_3g_cell_id *la = boost::get<odtone::mih::l2_3gpp_3g_cell_id>(addr)) {
+      char plmn[16];
+      sprintf(plmn, "%hhx:%hhx:%hhx", la->plmn_id[0], la->plmn_id[1], la->plmn_id[2]);
+      return str(boost::format("%s %d") % plmn % la->_cell_id);
+    }
+    else if  (const odtone::mih::l2_3gpp_2g_cell_id *la = boost::get<odtone::mih::l2_3gpp_2g_cell_id>(addr)) {
+      char plmn[16];
+      sprintf(plmn, "%hhx:%hhx:%hhx", la->plmn_id[0], la->plmn_id[1], la->plmn_id[2]);
+      return str(boost::format("%s %d %d") % plmn % la->_lac % la->_ci);
+    }
+    else if  (const odtone::mih::l2_3gpp_addr	    *la = boost::get<odtone::mih::l2_3gpp_addr>(addr)) {
+      return la->value;
+    }
+    else if  (const odtone::mih::l2_3gpp2_addr      *la = boost::get<odtone::mih::l2_3gpp2_addr>(addr)) {
+      return la->value;
+    }
+    else if  (const odtone::mih::other_l2_addr      *la = boost::get<odtone::mih::other_l2_addr>(addr)) {
+      return la->value;
+    }
+    return "null";
+}
+//-----------------------------------------------------------------------------
+std::string l2_3gpp_3g_cell_id2string(odtone::mih::l2_3gpp_3g_cell_id& addr)
+//-----------------------------------------------------------------------------
+{
+    char buffer[256];
+    int index = 0;
+
+    index += std::sprintf(&buffer[index], "plmn: -%hhx--%hhx--%hhx-\n", addr.plmn_id[0], addr.plmn_id[1], addr.plmn_id[2]);
+    index += std::sprintf(&buffer[index], "cell_id: %hhx\n", addr._cell_id);
+    return buffer;
+}
+//-----------------------------------------------------------------------------
+std::string link_id2string(odtone::mih::link_id linkP)
+//-----------------------------------------------------------------------------
+{
+    std::string s;
+    s = link_type2string(linkP.type.get()) + " " + link_addr2string(&linkP.addr);
+    return s;
+}
+//-----------------------------------------------------------------------------
+std::string ip_addr2string(odtone::mih::ip_addr ip_addrP) {
+//-----------------------------------------------------------------------------
+    std::string s;
+    switch (ip_addrP.type()) {
+	case odtone::mih::ip_addr::ipv4: s = "ipv4 "; break;
+	case odtone::mih::ip_addr::ipv6: s = "ipv6 "; break;
+	default: s = "Unkown type ";
+    }
+    s += ip_addrP.address();
+    return s;
+}
+//-----------------------------------------------------------------------------
+std::string ip_tuple2string(odtone::mih::ip_tuple ip_tupleP) {
+//-----------------------------------------------------------------------------
+    char buffer[128];
+    std::snprintf(buffer, 128, "%s/%d", ip_addr2string(ip_tupleP.ip).c_str(), ip_tupleP.port_val);
+    return buffer;
+}
+//-----------------------------------------------------------------------------
+std::string ip_proto2string(odtone::mih::proto ip_protoP) {
+//-----------------------------------------------------------------------------
+    switch (ip_protoP.get()) {
+	case odtone::mih::proto_tcp:	return "TCP";
+	case odtone::mih::proto_udp:	return "UDP";
+	default:			break;
+    }
+    return "Unknown IP protocol";
+}
+// TEMP : next 2 functions are commented to restore flow_id as a uint32
+// full structure will be updated later
+/*//-----------------------------------------------------------------------------
+std::string flow_id2string(odtone::mih::flow_id flowP) {
+//-----------------------------------------------------------------------------
+    std::string s;
+    odtone::mih::ip_tuple ip;
+    ip = flowP.src;
+    s = "SRC = " + ip_tuple2string(flowP.src);
+    s += ", DST = " + ip_tuple2string(flowP.dst);
+    s += ", PROTO = " + ip_proto2string(flowP.transport);
+    return s;
+}
+//-----------------------------------------------------------------------------
+std::string flow_id2string(odtone::mih::link_ac_param link_ac_paramP) {
+//-----------------------------------------------------------------------------
+    if (odtone::mih::resource_desc *res = boost::get<odtone::mih::resource_desc>(&link_ac_paramP.param)) {
+      return flow_id2string(res->fid);
+    }
+    else if (odtone::mih::flow_attribute *flow = boost::get<odtone::mih::flow_attribute>(&link_ac_paramP.param)) {
+      return flow_id2string(flow->id);
+    }
+    return "null";
+}*/
+//-----------------------------------------------------------------------------
+std::string link_ac_result2string(odtone::mih::link_ac_result resultP)
+//-----------------------------------------------------------------------------
+{
+    switch (resultP.get()) {
+	case odtone::mih::link_ac_success:	return "SUCCESS"; break;
+	case odtone::mih::link_ac_failure:	return "FAILURE"; break;
+	case odtone::mih::link_ac_refused:	return "REFUSED"; break;
+	case odtone::mih::link_ac_incapable:	return "INCAPABLE"; break;
+	default:				break;
+    }
+    return "Unknown action result";
+}
+//-----------------------------------------------------------------------------
+std::string link_actions_req2string(odtone::mih::link_action_req link_act_reqP) {
+//-----------------------------------------------------------------------------
+    std::string s;
+
+    s = link_id2string(link_act_reqP.id);
+
+    if(link_act_reqP.action.type == odtone::mih::link_ac_type_none)                      s += ", AC_TYPE_NONE";
+    if(link_act_reqP.action.type == odtone::mih::link_ac_type_disconnect)                s += ", AC_TYPE_DISCONNECT";
+    if(link_act_reqP.action.type == odtone::mih::link_ac_type_low_power)                 s += ", AC_TYPE_LOW_POWER";
+    if(link_act_reqP.action.type == odtone::mih::link_ac_type_power_down)                s += ", AC_TYPE_POWER_DOWN";
+    if(link_act_reqP.action.type == odtone::mih::link_ac_type_power_up)                  s += ", AC_TYPE_POWER_UP";
+    if(link_act_reqP.action.type == odtone::mih::link_ac_type_flow_attr)                 s += ", AC_TYPE_FLOW_ATTR";
+    if(link_act_reqP.action.type == odtone::mih::link_ac_type_link_activate_resources)   s += ", AC_TYPE_ACTIVATE_RESOURCES";
+    if(link_act_reqP.action.type == odtone::mih::link_ac_type_link_deactivate_resources) s += ", AC_TYPE_DEACTIVATE_RESOURCES";
+
+    if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_data_fwd_req))            s += ", AC_ATTR_DATA_FWD_REQ";
+    if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_scan))                    s += ", AC_ATTR_SCAN";
+    if(link_act_reqP.action.attr.get(odtone::mih::link_ac_attr_res_retain))              s += ", AC_ATTR_RES_RETAIN";
+
+    s += ", " + StringOf(link_act_reqP.ex_time) + " ms";
+    return s;
+}
+//-----------------------------------------------------------------------------
+std::string net_type_addr_list2string(boost::optional<odtone::mih::net_type_addr_list> ntalP) {
+//-----------------------------------------------------------------------------
+    std::string                s;
+    std::ostringstream         stream;
+    odtone::mih::net_type_addr net_type_addr;
+
+    for (odtone::mih::net_type_addr_list::iterator i = ntalP->begin(); i != ntalP->end(); i++)
+    {
+        net_type_addr = boost::get<odtone::mih::net_type_addr>(*i);
+        stream << net_type_addr;
+        if (i != ntalP->begin()) {
+            stream <<  " / ";
+        }
+    }
+    s =  stream.str();
+    return s;
+}
+
+
+
+/**
+ * Parse supported commands.
+ *
+ * @param cfg Configuration options.
+ * @return An optional list of supported commands.
+ */
+boost::optional<odtone::mih::mih_cmd_list> parse_supported_commands(const odtone::mih::config &cfg)
+{
+	using namespace boost;
+
+	odtone::mih::mih_cmd_list commands;
+
+	std::map<std::string, odtone::mih::mih_cmd_list_enum> enum_map;
+	enum_map["mih_link_get_parameters"]       = odtone::mih::mih_cmd_link_get_parameters;
+	enum_map["mih_link_configure_thresholds"] = odtone::mih::mih_cmd_link_configure_thresholds;
+	enum_map["mih_link_actions"]              = odtone::mih::mih_cmd_link_actions;
+	enum_map["mih_net_ho_candidate_query"]    = odtone::mih::mih_cmd_net_ho_candidate_query;
+	enum_map["mih_net_ho_commit"]             = odtone::mih::mih_cmd_net_ho_commit;
+	enum_map["mih_n2n_ho_query_resources"]    = odtone::mih::mih_cmd_n2n_ho_query_resources;
+	enum_map["mih_n2n_ho_commit"]             = odtone::mih::mih_cmd_n2n_ho_commit;
+	enum_map["mih_n2n_ho_complete"]           = odtone::mih::mih_cmd_n2n_ho_complete;
+	enum_map["mih_mn_ho_candidate_query"]     = odtone::mih::mih_cmd_mn_ho_candidate_query;
+	enum_map["mih_mn_ho_commit"]              = odtone::mih::mih_cmd_mn_ho_commit;
+	enum_map["mih_mn_ho_complete"]            = odtone::mih::mih_cmd_mn_ho_complete;
+
+	std::string tmp = cfg.get<std::string>(kConf_MIH_Commands);
+	__trim(tmp, ' ');
+
+	char_separator<char> sep1(",");
+	tokenizer< char_separator<char> > list_tokens(tmp, sep1);
+
+	BOOST_FOREACH(std::string str, list_tokens) {
+		if(enum_map.find(str) != enum_map.end()) {
+			commands.set((odtone::mih::mih_cmd_list_enum) enum_map[str]);
+		}
+	}
+
+	return commands;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/**
+ * This class provides an implementation of an IEEE 802.21 MIH-User.
+ */
+class mih_user : boost::noncopyable {
+public:
+    /**
+     * Construct the MIH-User.
+     *
+     * @param cfg Configuration options.
+     * @param io The io_service object that the MIH-User will use to
+     * dispatch handlers for any asynchronous operations performed on the socket.
+     */
+    mih_user(const odtone::mih::config& cfg, boost::asio::io_service& io);
+
+    /**
+     * Destruct the MIH-User.
+     */
+    ~mih_user();
+
+protected:
+    /**
+     * User registration handler.
+     *
+     * @param cfg Configuration options.
+     * @param ec Error Code.
+     */
+    void user_reg_handler(const odtone::mih::config& cfg, const boost::system::error_code& ec);
+    /**
+     * Default MIH event handler.
+     *
+     * @param msg Received event notification.
+     * @param ec Error code.
+     */
+    void event_handler(odtone::mih::message& msg, const boost::system::error_code& ec);
+    /**
+     * MIH receive message handler.
+     *
+     * @param msg Received message.
+     * @param ec Error code.
+     */
+    void receive_handler(odtone::mih::message& msg, const boost::system::error_code& ec);
+
+    void send_MIH_User_Register_indication(const odtone::mih::config& cfg);
+
+    void send_MIH_Capability_Discover_request(void);
+    void receive_MIH_Capability_Discover_confirm(odtone::mih::message& msg);
+
+    void send_MIH_Event_Subscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt);
+    void receive_MIH_Event_Subscribe_confirm(odtone::mih::message& msg);
+
+    void send_MIH_Event_Unsubscribe_request(void);
+    void send_MIH_Event_Unsubscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt);
+    void receive_MIH_Event_Unsubscribe_confirm(odtone::mih::message& msg);
+
+    void send_MIH_Link_Actions_request(const odtone::mih::link_id& link, odtone::mih::link_ac_type type);
+    void receive_MIH_Link_Actions_confirm(odtone::mih::message& msg);
+    void receive_MIH_Link_Parameters_Report(odtone::mih::message& msg, const boost::system::error_code& ec);
+
+    void send_MIH_Link_Configure_Thresholds_request(odtone::mih::message& msg, const boost::system::error_code& ec);
+    void receive_MIH_Link_Configure_Thresholds_confirm(odtone::mih::message& msg, const boost::system::error_code& ec);
+
+private:
+    odtone::sap::user          _mihf;    /**< User SAP helper.       */
+    odtone::mih::id            _mihfid;  /**< MIHF destination ID.   */
+    odtone::mih::id            _mihuserid;   /**< MIH_USER ID.       */
+
+    odtone::mih::ip_addr       _mihf_ip;      /**< MIHF IP address        */
+    odtone::mih::port          _mihf_lport;   /**< MIHF local port number */
+
+    odtone::mih::link_id_list  _link_id_list;    /**< List of network link identifiers   */
+    odtone::mih::mih_evt_list  _subs_evt_list;   /**< List of subscribed link events */
+
+    odtone::mih::link_ac_type  _last_link_action_type;
+    odtone::uint               _current_link_action_request, _nb_of_link_action_requests;
+    odtone::uint               link_threshold_request, link_measures_request, link_measures_counter;
+    odtone::mih::link_id       rcv_link_id;
+
+    static const odtone::uint  _max_link_action_requests = 4;
+    odtone::uint               _num_thresholds_request;
+
+    void receive_MIH_Link_Detected_indication(odtone::mih::message& msg);
+    void send_MIH_Link_Action_Power_Up_plus_scan_request(const odtone::mih::link_id& link);
+    void receive_MIH_Link_Up_indication(odtone::mih::message& msg);
+
+    void receive_MIH_Link_Down_indication(odtone::mih::message& msg);
+
+    void receive_MIH_Link_Going_Down_indication(odtone::mih::message& msg);
+
+};
+
+//-----------------------------------------------------------------------------
+mih_user::mih_user(const odtone::mih::config& cfg, boost::asio::io_service& io)
+  : _mihf(cfg, io, boost::bind(&mih_user::event_handler, this, _1, _2)),
+    _last_link_action_type(odtone::mih::link_ac_type_none),
+    _current_link_action_request(0), _nb_of_link_action_requests(NB_OF_RESOURCES), _num_thresholds_request(0)
+//-----------------------------------------------------------------------------
+{
+    odtone::mih::octet_string user_id = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_id);
+    _mihuserid.assign(user_id.c_str());
+
+    odtone::mih::octet_string dest_id = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIH_SAP_dest);
+    _mihfid.assign(dest_id.c_str());
+
+    odtone::mih::octet_string src = cfg.get<odtone::mih::octet_string>(odtone::sap::kConf_MIHF_Ip);
+    boost::asio::ip::address ip = boost::asio::ip::address::from_string(src);
+    if (ip.is_v4()) {
+        odtone::mih::ip_addr ip_addr(odtone::mih::ip_addr::ipv4, src);
+        _mihf_ip = ip_addr;
+    } else if (ip.is_v6()) {
+        odtone::mih::ip_addr ip_addr(odtone::mih::ip_addr::ipv6, src);
+        _mihf_ip = ip_addr;
+    }
+
+    _mihf_lport = cfg.get<odtone::mih::port>(odtone::sap::kConf_MIHF_Local_Port);
+
+    //_nb_of_link_action_requests = NB_OF_RESOURCES;
+    if (_nb_of_link_action_requests > _max_link_action_requests) {
+        _nb_of_link_action_requests = _max_link_action_requests;
+    }
+
+    _link_id_list.clear();
+    _subs_evt_list.clear();
+    link_threshold_request = 0;
+    link_measures_request =0;
+    link_measures_counter =0;
+    log_(0, "[MSC_NEW]["+getTimeStamp4Log()+"][MIH-USER="+_mihuserid.to_string()+"]\n");
+
+    // Send MEDIEVAL specific MIH_User_Register.indication message to the MIH-F
+    mih_user::send_MIH_User_Register_indication(cfg);
+}
+
+//-----------------------------------------------------------------------------
+mih_user::~mih_user()
+//-----------------------------------------------------------------------------
+{
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::user_reg_handler(const odtone::mih::config& cfg, const boost::system::error_code& ec)
+//-----------------------------------------------------------------------------
+{
+     log_(0, "MIH-User register result: ", ec.message(), "\n");
+
+    //
+    // Let's fire a capability discover request to get things moving
+    //
+    mih_user::send_MIH_Capability_Discover_request();
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::event_handler(odtone::mih::message& msg, const boost::system::error_code& ec)
+//-----------------------------------------------------------------------------
+{
+    if (ec) {
+        log_(0, __FUNCTION__, " error: ", ec.message());
+        return;
+    }
+
+    switch (msg.mid()) {
+    case odtone::mih::indication::link_detected:
+        mih_user::receive_MIH_Link_Detected_indication(msg);
+        break;
+
+    case odtone::mih::indication::link_up:
+        mih_user::receive_MIH_Link_Up_indication(msg);
+        if (_num_thresholds_request == 0) {
+            mih_user::send_MIH_Link_Configure_Thresholds_request(msg, ec);
+            _num_thresholds_request += 1;;
+        }
+        break;
+
+    case odtone::mih::indication::link_down:
+        mih_user::receive_MIH_Link_Down_indication(msg);
+        break;
+
+    case odtone::mih::indication::link_going_down:
+        mih_user::receive_MIH_Link_Going_Down_indication(msg);
+        break;
+
+    case odtone::mih::indication::link_handover_imminent:
+        log_(0, "MIH-User has received a local event \"link_handover_imminent\"");
+        break;
+
+    case odtone::mih::indication::link_handover_complete:
+        log_(0, "MIH-User has received a local event \"link_handover_complete\"");
+        break;
+
+    case odtone::mih::indication::link_parameters_report:
+        //log_(0, "MIH-User has received a local event \"link_parameters_report\"");
+        mih_user::receive_MIH_Link_Parameters_Report(msg, ec);
+        /*if (link_threshold_request == 0){
+            mih_user::send_MIH_Link_Configure_Thresholds_request(msg, ec);
+            link_threshold_request =1;
+        } else if (link_threshold_request == 1){
+            link_measures_counter ++;
+            // Stop measures after 5 reports
+            if (link_measures_counter == NUM_PARM_REPORT){
+                mih_user::send_MIH_Link_Configure_Thresholds_request(msg, ec);
+            }
+        }*/
+        break;
+
+    case odtone::mih::indication::link_pdu_transmit_status:
+        log_(0, "MIH-User has received a local event \"link_pdu_transmit_status\"");
+        break;
+
+    case odtone::mih::confirm::link_configure_thresholds:
+        mih_user::receive_MIH_Link_Configure_Thresholds_confirm(msg, ec);
+        break;
+
+    default:
+        log_(0, "MIH-User has received UNKNOWN local event");
+        break;
+    }
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::receive_handler(odtone::mih::message& msg, const boost::system::error_code& ec)
+//-----------------------------------------------------------------------------
+{
+    if (ec) {
+        log_(0, __FUNCTION__, " error: ", ec.message());
+        return;
+    }
+
+    switch (msg.mid()) {
+
+    case odtone::mih::confirm::capability_discover:
+        mih_user::receive_MIH_Capability_Discover_confirm(msg);
+        break;
+
+    case odtone::mih::confirm::event_subscribe:
+        mih_user::receive_MIH_Event_Subscribe_confirm(msg);
+        break;
+
+    case odtone::mih::confirm::event_unsubscribe:
+        mih_user::receive_MIH_Event_Unsubscribe_confirm(msg);
+        break;
+
+    case odtone::mih::confirm::link_actions:
+        mih_user::receive_MIH_Link_Actions_confirm(msg);
+        break;
+
+    default:
+        log_(0, "MIH-User has received UNKNOWN message (", msg.mid(), ")\n");
+        break;
+	}
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::receive_MIH_Link_Detected_indication(odtone::mih::message& msg)
+//-----------------------------------------------------------------------------
+{
+    log_(0, "MIH_Link_Detected.indication - RECEIVED - Begin\n");
+    odtone::mih::link_det_info                ldi;
+    odtone::mih::link_det_info_list           ldil;
+    odtone::mih::link_det_info_list::iterator it_ldil;
+    odtone::mih::link_id                      lid;
+
+    msg >> 	odtone::mih::indication() & odtone::mih::tlv_link_det_info_list(ldil);
+
+    log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Detected.indication --->]["+msg.destination().to_string()+"]\n");
+    for(it_ldil = ldil.begin(); it_ldil != ldil.end(); it_ldil++) {
+            ldi = *it_ldil;
+            log_(0, "\tMIH_Link_Detected.indication - network_id:........", ldi.network_id.c_str());
+            log_(0, "\tMIH_Link_Detected.indication - net_aux_id:........", ldi.net_aux_id.c_str());
+            log_(0, "\tMIH_Link_Detected.indication - sig_strength:......TO DO");//, ldi.signal);
+            log_(0, "\tMIH_Link_Detected.indication - sinr:..............", ldi.sinr);
+            log_(0, "\tMIH_Link_Detected.indication - data_rate:.........", ldi.data_rate);
+            log_(0, "\tMIH_Link_Detected.indication - data_rate:.........", ldi.data_rate);
+            log_(0, "\tMIH_Link_Detected.indication - mih_capabilities:..", ldi.data_rate);
+            log_(0, "\tMIH_Link_Detected.indication - net_capabilities:..TO DO");//, ldi.net_capabilities);
+
+    }
+    // Display message parameters
+    // TODO: for each link_det_info in the list {display LINK_DET_INFO}
+
+    // send Link_Action / Power Up
+    lid.type = odtone::mih::link_type_lte;
+    lid.addr = ldi.id.addr;
+    //send_MIH_Link_Action_Power_Up_plus_scan_request(lid);
+    log_(0, "MIH_Link_Detected.indication - End\n");
+}
+
+
+//-----------------------------------------------------------------------------
+void mih_user::send_MIH_Link_Action_Power_Up_plus_scan_request(const odtone::mih::link_id& link)
+//-----------------------------------------------------------------------------
+{
+    odtone::mih::message          m;
+    odtone::mih::link_action_list lal;
+    odtone::mih::link_action_req  link_act_req;
+    //struct null                   n;
+
+    link_act_req.id               = link;
+    link_act_req.action.type      = odtone::mih::link_ac_type_power_up;
+    link_act_req.action.attr.clear();
+    link_act_req.action.attr.set(odtone::mih::link_ac_attr_scan);
+
+    link_act_req.ex_time            = 5000; // in ms
+
+    lal.push_back(link_act_req);
+
+    m << odtone::mih::request(odtone::mih::request::link_actions)
+      & odtone::mih::tlv_link_action_list(lal);
+    m.source(_mihuserid);
+    m.destination(_mihfid);
+
+    log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Link_Actions.request\\n"+link_actions_req2string(link_act_req)+" --->]["+m.destination().to_string()+"]\n");
+
+    _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2));
+
+    log_(0, "MIH-User has sent Link_Actions.request to ", m.destination().to_string());
+    log_(0, "   - LINK_ID - Link identifier:  ", link_id2string(link).c_str());
+    log_(0, "   - LINK_ACTIONS - Link Actions: " + link_actions_req2string(link_act_req) + "\n");
+
+    log_(0, "MIH_Link_Action_Power_Up_request - SENT\n");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::receive_MIH_Link_Up_indication(odtone::mih::message& msg)
+//-----------------------------------------------------------------------------
+{
+    log_(0, "MIH_Link_Up.indication - RECEIVED - Begin\n");
+
+    odtone::mih::link_tuple_id link;
+//        odtone::mih::tlv_old_access_router oldAR;
+
+    msg >> 	odtone::mih::indication() & odtone::mih::tlv_link_identifier(link);
+//          & odtone::mih::tlv_old_access_router(oar);
+
+    log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Up.indication --->]["+msg.destination().to_string()+"]\n");
+
+    // Display message parameters
+    log_(0, "   - LINK_ID - Link identifier:  ", link_id2string(link).c_str(), "\n");
+
+    log_(0, "MIH_Link_Up.indication - End\n");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::receive_MIH_Link_Down_indication(odtone::mih::message& msg)
+//-----------------------------------------------------------------------------
+{
+    odtone::mih::link_tuple_id               link;
+    boost::optional<odtone::mih::link_addr>  addr;
+    odtone::mih::link_dn_reason              ldr;
+
+    log_(0, "MIH_Link_Down.indication - RECEIVED - Begin\n");
+    msg >> odtone::mih::indication()
+      & odtone::mih::tlv_link_identifier(link)
+      & odtone::mih::tlv_old_access_router(addr)
+      & odtone::mih::tlv_link_dn_reason(ldr);
+
+//  log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Down.indication\\n"+link_down_reason2string(ldr).c_str()+" --->]["+msg.destination().to_string()+"]\n");
+
+    //Display message parameters
+    log_(0, "   - LINK_ID - Link identifier:  ", link_id2string(link).c_str(), "\n");
+//  log_(0, "   - LINK_DN_REASON - Link down reason:  ", link_down_reason2string(ldr).c_str(), "\n");
+
+    log_(0, "MIH_Link_Down.indication - End\n");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::receive_MIH_Link_Going_Down_indication(odtone::mih::message& msg)
+//-----------------------------------------------------------------------------
+{
+    log_(0, "MIH_Link_Going_Down.indication - RECEIVED - Begin\n");
+
+    odtone::mih::link_tuple_id   link;
+    odtone::mih::link_gd_reason  lgd;
+    odtone::mih::link_ac_ex_time ex_time;
+
+    msg >> odtone::mih::indication()
+      & odtone::mih::tlv_link_identifier(link)
+      & odtone::mih::tlv_time_interval(ex_time)
+      & odtone::mih::tlv_link_gd_reason(lgd);
+
+    log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Going_Down.indication\\n"+link_going_down_reason2string(lgd).c_str()+" --->]["+msg.destination().to_string()+"]\n");
+
+    // Display message parameters
+    log_(0, "   - LINK_ID - Link identifier:  ", link_id2string(link).c_str());
+    log_(0, "   - Time Interval:", (ex_time/256));
+    log_(0, "   - LINK_GD_REASON - Link going down reason: ", link_going_down_reason2string(lgd).c_str(), "\n");
+
+    log_(0, "MIH_Link_Going_Down.indication - End\n");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::receive_MIH_Link_Parameters_Report(odtone::mih::message& msg, const boost::system::error_code& ec)
+//-----------------------------------------------------------------------------
+{
+    odtone::mih::link_tuple_id link;
+    odtone::mih::link_param_rpt_list lprl;
+
+    msg >> odtone::mih::indication()
+           & odtone::mih::tlv_link_identifier(link)
+           & odtone::mih::tlv_link_param_rpt_list(lprl);
+
+    log_(0, "");
+    log_(0, "MIH_Link_Parameters_Report.indication - RECEIVED - Begin");
+    log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Parameters_Report.indication --->]["+msg.destination().to_string()+"]\n");
+    log_(0, "  - LINK_TUPLE_ID - Link identifier:  ", link_id2string(link).c_str());
+    log_(0, "MIH_Link_Parameters_Report.indication - End");
+}
+
+
+//-----------------------------------------------------------------------------
+void mih_user::send_MIH_User_Register_indication(const odtone::mih::config& cfg)
+//-----------------------------------------------------------------------------
+{
+	odtone::mih::message m;
+	boost::optional<odtone::mih::mih_cmd_list> supp_cmd = parse_supported_commands(cfg);
+
+	m << odtone::mih::indication(odtone::mih::indication::user_register)
+	    & odtone::mih::tlv_command_list(supp_cmd);
+	m.source(_mihuserid);
+	m.destination(_mihfid);
+
+	log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_User_Register.indication --->]["+m.destination().to_string()+"]\n");
+
+	_mihf.async_send(m, boost::bind(&mih_user::user_reg_handler, this, boost::cref(cfg), _2));
+
+	log_(0, "MIH_User_Register.indication - SENT (towards its local MIHF)\n");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::send_MIH_Capability_Discover_request(void)
+//-----------------------------------------------------------------------------
+{
+	odtone::mih::message m;
+	m << odtone::mih::request(odtone::mih::request::capability_discover);
+	m.source(_mihuserid);
+	m.destination(_mihfid);
+
+	log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Capability_Discover.request --->]["+m.destination().to_string()+"]\n");
+
+	_mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2));
+
+	log_(0, "MIH_Capability_Discover.request - SENT (towards its local MIHF)\n");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::receive_MIH_Capability_Discover_confirm(odtone::mih::message& msg)
+//-----------------------------------------------------------------------------
+{
+    log_(0, "MIH_Capability_Discover.confirm - RECEIVED - Begin\n");
+
+    odtone::mih::status                              st;
+    boost::optional<odtone::mih::net_type_addr_list> ntal;
+    boost::optional<odtone::mih::mih_evt_list>       evt;
+    boost::optional<odtone::mih::mih_cmd_list>       cmd;
+
+    msg >> odtone::mih::confirm()
+            & odtone::mih::tlv_status(st)
+            & odtone::mih::tlv_net_type_addr_list(ntal)
+            & odtone::mih::tlv_event_list(evt)
+            & odtone::mih::tlv_command_list(cmd);
+
+    log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Capability_Discover.confirm"+
+         "\\nstatus="+status2string(st).c_str()+
+         "\\nEvent list="+evt2string(evt.get()).c_str()+
+         "\\nNet type addr list=" + net_type_addr_list2string(ntal).c_str()+
+         " --->]["+msg.destination().to_string()+"]\n");
+
+    // Display message parameters
+    log_(0, "  - STATUS: ", status2string(st).c_str(), " (", st.get(), ")");
+    if (evt) {
+      log_(0, "  - MIH_EVT_LIST - Event List:  ", evt2string(evt.get()).c_str());
+    }
+    if (cmd) {
+      log_(0, "  - MIH_CMD_LIST - Command List:  ", cmd2string(cmd.get()).c_str());
+    }
+    if (ntal) {
+      log_(0, "  - LIST(NET_TYPE_ADDR) - Network Types and Link Address: ", net_type_addr_list2string(ntal).c_str());
+          //Store link address
+          for (odtone::mih::net_type_addr_list::iterator i = ntal->begin(); i != ntal->end(); i++)
+          {
+            rcv_link_id.addr = i->addr;
+            rcv_link_id.type = boost::get<odtone::mih::link_type>(i->nettype.link);
+          }
+    }
+    log_(0, "");
+
+    //
+    // event subscription
+    //
+    // For every interface the MIHF sent in the
+    // Capability_Discover.response send an Event_Subscribe.request
+    // for all availabe events
+    //
+    if (ntal && evt) {
+        _subs_evt_list = evt.get(); // save the list of subscribed link events
+        for (odtone::mih::net_type_addr_list::iterator i = ntal->begin(); i != ntal->end(); i++) {
+            if (i->nettype.link.which() == 1)
+            {
+                odtone::mih::link_tuple_id li;
+
+                li.addr = i->addr;
+                li.type = boost::get<odtone::mih::link_type>(i->nettype.link);
+                _link_id_list.push_back(li);    // save the link identifier of the network interface
+
+                mih_user::send_MIH_Event_Subscribe_request(li, evt.get());
+            }
+        }
+    }
+
+    log_(0, "MIH_Capability_Discover.confirm - End\n");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::send_MIH_Event_Subscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt)
+//-----------------------------------------------------------------------------
+{
+    odtone::mih::message m;
+
+    m << odtone::mih::request(odtone::mih::request::event_subscribe)
+      & odtone::mih::tlv_link_identifier(li)
+      & odtone::mih::tlv_event_list(evt);
+    m.source(_mihuserid);
+    m.destination(_mihfid);
+
+    log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Event_Subscribe.request"+
+         "\\nLink="+link_id2string(li).c_str()+
+         "\\nEvent list="+evt2string(evt).c_str()+
+         " --->]["+m.destination().to_string()+"]\n");
+
+    _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2));
+
+    log_(0, "MIH-User has sent Event_Subscribe.request to ", m.destination().to_string());
+    log_(0, "  - LINK_TUPLE_ID - Link identifier:  ", link_id2string(li).c_str());
+    log_(0, "  - MIH_EVT_LIST - Event List:  ", evt2string(evt).c_str(), "\n");
+
+    log_(0, "MIH_Event_Subscribe.request - SENT\n");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::receive_MIH_Event_Subscribe_confirm(odtone::mih::message& msg)
+//-----------------------------------------------------------------------------
+{
+    log_(0, "MIH_Event_Subscribe.confirm(", msg.tid(), ") - RECEIVED - Begin\n");
+
+    odtone::mih::status                        st;
+    odtone::mih::link_tuple_id                 link;
+    boost::optional<odtone::mih::mih_evt_list> evt;
+
+    msg >> odtone::mih::confirm()
+      & odtone::mih::tlv_status(st)
+      & odtone::mih::tlv_link_identifier(link)
+      & odtone::mih::tlv_event_list(evt);
+
+    if (evt) {
+        log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Subscribe.confirm"+
+             "\\nstatus="+status2string(st).c_str()+
+             "\\nLink="+link_id2string(link).c_str()+
+             "\\nEvent list="+evt2string(evt.get()).c_str()+
+             " --->]["+msg.destination().to_string()+"]\n");
+    } else {
+        log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Subscribe.confirm"+
+             "\\nstatus="+status2string(st).c_str()+
+             "\\nLink="+link_id2string(link).c_str()+
+             " --->]["+msg.destination().to_string()+"]\n");
+    }
+
+    // Display message parameters
+    log_(0, "  - STATUS: ", status2string(st).c_str(), " (", st.get(), ")");
+    log_(0, "  - LINK_TUPLE_ID - Link identifier:  ", link_id2string(link).c_str());
+    if (evt) {
+      log_(0, "  - MIH_EVT_LIST - Event List:  ", evt2string(evt.get()).c_str());
+    }
+    log_(0, "");
+
+    //mih_user::send_MIH_Link_Actions_request(link, odtone::mih::link_ac_type_link_activate_resources);
+    //log_(0, "TEMP : Resource scenario deactivated\n");
+
+    log_(0, "MIH_Event_Subscribe.confirm - End\n");
+    mih_user::send_MIH_Link_Action_Power_Up_plus_scan_request(link);
+
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::send_MIH_Event_Unsubscribe_request(void)
+//-----------------------------------------------------------------------------
+{
+    odtone::mih::link_tuple_id li;
+
+    // For every interface the MIH user received in the
+    // Capability_Discover.confirm, send an Event_Unsubscribe.request
+    // for all subscribed events
+    for (odtone::mih::link_id_list::iterator i = _link_id_list.begin(); i != _link_id_list.end(); i++) {
+        li.type = i->type;
+        li.addr = i->addr;
+        mih_user::send_MIH_Event_Unsubscribe_request(li, _subs_evt_list);
+    }
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::send_MIH_Event_Unsubscribe_request(odtone::mih::link_tuple_id& li, odtone::mih::mih_evt_list& evt)
+//-----------------------------------------------------------------------------
+{
+    odtone::mih::message m;
+
+    m << odtone::mih::request(odtone::mih::request::event_unsubscribe)
+      & odtone::mih::tlv_link_identifier(li)
+      & odtone::mih::tlv_event_list(evt);
+    m.source(_mihuserid);
+    m.destination(_mihfid);
+
+    log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Event_Unsubscribe.request"+
+         "\\nLink="+link_id2string(li).c_str()+
+         "\\nEvent list="+evt2string(evt).c_str()+
+         " --->]["+m.destination().to_string()+"]\n");
+
+    _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2));
+
+    log_(0, "MIH-User has sent Event_Unsubscribe.request to ", m.destination().to_string());
+    log_(0, "  - LINK_TUPLE_ID - Link identifier:  ", link_id2string(li).c_str());
+    log_(0, "  - MIH_EVT_LIST - Event List:  ", evt2string(evt).c_str(), "\n");
+
+    log_(0, "MIH_Event_Unsubscribe.request - SENT\n");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::receive_MIH_Event_Unsubscribe_confirm(odtone::mih::message& msg)
+//-----------------------------------------------------------------------------
+{
+    log_(0, "MIH_Event_Unsubscribe.confirm(", msg.tid(), ") - RECEIVED - Begin\n");
+
+    odtone::mih::status st;
+    odtone::mih::link_tuple_id link;
+    boost::optional<odtone::mih::mih_evt_list> evt;
+
+    msg >>  odtone::mih::confirm()
+      & odtone::mih::tlv_status(st)
+      & odtone::mih::tlv_link_identifier(link)
+      & odtone::mih::tlv_event_list(evt);
+
+    if (evt) {
+        log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Unsubscribe.confirm"+
+             "\\nstatus="+status2string(st).c_str()+
+             "\\nLink="+link_id2string(link).c_str()+
+             "\\nEvent list="+evt2string(evt.get()).c_str()+
+             " --->]["+msg.destination().to_string()+"]\n");
+    } else {
+        log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Event_Unsubscribe.confirm"+
+             "\\nstatus="+status2string(st).c_str()+
+             "\\nLink="+link_id2string(link).c_str()+
+             " --->]["+msg.destination().to_string()+"]\n");
+    }
+
+    // Display message parameters
+    log_(0, "  - STATUS: ", status2string(st).c_str(), " (", st.get(), ")");
+    log_(0, "  - LINK_TUPLE_ID - Link identifier:  ", link_id2string(link).c_str());
+    if (evt) {
+      log_(0, "  - MIH_EVT_LIST - Event List:  ", evt2string(evt.get()).c_str());
+    }
+    log_(0, "");
+
+    log_(0, "MIH_Event_Unsubscribe.confirm - End");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::send_MIH_Link_Actions_request(const odtone::mih::link_id& link, odtone::mih::link_ac_type type)
+//-----------------------------------------------------------------------------
+{
+    odtone::mih::message m;
+    odtone::mih::link_action_list lal;
+    odtone::mih::link_action_req link_act_req;
+
+    link_act_req.id = link;
+    link_act_req.action.type = type;
+
+    _last_link_action_type = type;
+
+    // Initialize resource parameters
+    odtone::mih::resource_desc res;
+
+    res.lid       = link;       // Link identifier
+    res.data_rate = 128000;     // bit rate
+    res.jumbo     = false;      // jumbo disable
+    res.multicast = false;      // multicast disable
+
+    odtone::mih::qos qos;       // Class Of Service
+    qos.value     = 56;
+    res.qos_val   = qos;
+    res.fid = 555 + _current_link_action_request;
+
+// 	// Flow identifier
+// 	res.fid.src.ip = _mihf_ip;
+// 	res.fid.src.port_val = _mihf_lport;
+// 
+// 	if (mih_user::_current_link_action_request == 0) {
+// 	  res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6,
+// 						"2001:0660:0382:0014:0335:0600:8014:9150"); // DUMMY
+// 	}
+// 	else if (mih_user::_current_link_action_request == 1) {
+// 	  res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6,
+// 						"2001:0660:0382:0014:0335:0600:8014:9151"); // DUMMY
+// 	}
+// 	else if (mih_user::_current_link_action_request == 2) {
+// 	  res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6,
+// 						"FF3E:0020:2001:0DB8:0000:0000:0000:0043"); // DUMMY
+// 	  res.multicast = true;
+// 	}
+// 	else if (mih_user::_current_link_action_request == 3) {
+// 	  res.fid.dst.ip = odtone::mih::ip_addr(odtone::mih::ip_addr::ipv6,
+// 						"2001:0660:0382:0014:0335:0600:8014:9153"); // DUMMY
+// 	}
+// 	res.fid.dst.port_val = 1235; // DUMMY
+// 	res.fid.transport = odtone::mih::proto_udp;
+
+    link_act_req.action.param.param = res;
+
+    link_act_req.ex_time = 0;
+
+    lal.push_back(link_act_req);
+
+    m << odtone::mih::request(odtone::mih::request::link_actions)
+      & odtone::mih::tlv_link_action_list(lal);
+    m.source(_mihuserid);
+    m.destination(_mihfid);
+
+    log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ m.source().to_string() +"][--- MIH_Link_Actions.request\\n"+link_actions_req2string(link_act_req)+" --->]["+m.destination().to_string()+"]\n");
+
+    _mihf.async_send(m, boost::bind(&mih_user::receive_handler, this, _1, _2));
+ 
+    log_(0, "MIH-User has sent Link_Actions.request to ", m.destination().to_string());
+    log_(0, "   - LINK_ID - Link identifier:  ", link_id2string(link).c_str());
+    log_(0, "   - FLOW_ID - Flow identifier:  ", res.fid);
+//TEMP  log_(0, "   - FLOW_ID - Flow identifier:  ", flow_id2string(link_act_req.action.param).c_str());
+    log_(0, "   - LINK_ACTIONS - Link Actions: " + link_actions_req2string(link_act_req) + "\n");
+
+    log_(0, "MIH_Link_Actions.request - SENT\n");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::receive_MIH_Link_Actions_confirm(odtone::mih::message& msg)
+//-----------------------------------------------------------------------------
+{
+    log_(0, "MIH_Link_Actions.confirm - RECEIVED - Begin\n");
+
+    odtone::mih::status st;
+    boost::optional<odtone::mih::link_action_rsp_list> larl;
+
+    msg >> odtone::mih::confirm()
+      & odtone::mih::tlv_status(st)
+      & odtone::mih::tlv_link_action_rsp_list(larl);
+
+    log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ msg.source().to_string() +"][--- MIH_Link_Actions.confirm"+
+         "\\nstatus="+status2string(st).c_str()+
+         " --->]["+msg.destination().to_string()+"]\n");
+
+    // Display message parameters
+    log_(0, "  - STATUS: ", status2string(st).c_str(), " (", st.get(), ")");
+    if (larl) {
+        log_(0, "  - LINK ACTION RSP LIST - Length:", larl.get().size());
+        for (odtone::mih::link_action_rsp_list::iterator i = larl->begin(); i != larl->end(); i++)
+        {
+        log_(0, "\tLINK_ID: ", link_id2string(i->id).c_str(),
+             ", LINK_AC_RESULT: ", link_ac_result2string(i->result).c_str());
+        }
+    }
+    log_(0, "");
+
+    // 1st scenario: Sequentially activate and deactivate each resource
+#ifdef SCENARIO_1
+	if (larl) {
+	    odtone::mih::link_action_rsp *rsp = &larl->front();
+	    if (_current_link_action_request < _nb_of_link_action_requests) {
+	        if (_last_link_action_type == odtone::mih::link_ac_type_link_activate_resources) {
+		    if (rsp->result.get() == odtone::mih::link_ac_success) {
+		        mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_deactivate_resources);
+			_current_link_action_request += 1;
+		    }
+		}
+		else if (_last_link_action_type == odtone::mih::link_ac_type_link_deactivate_resources) {
+		    mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_activate_resources);
+		}
+	    }
+	    else { // Ends the scenario
+	        mih_user::send_MIH_Event_Unsubscribe_request();
+	    }
+	}
+#endif // SCENARIO_1
+
+#ifdef SCENARIO_2
+	// 2nd scenario: Activate all resources, then deactivate all resources
+	if (larl.get().size() > 0) {
+	    odtone::mih::link_action_rsp *rsp = &larl->front();
+	    if (++_current_link_action_request < _nb_of_link_action_requests) {
+		if (_last_link_action_type == odtone::mih::link_ac_type_link_activate_resources) {
+		    mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_activate_resources);
+		}
+		else if (_last_link_action_type == odtone::mih::link_ac_type_link_deactivate_resources) {
+		    mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_deactivate_resources);
+		}
+	    }
+	    else if (_last_link_action_type == odtone::mih::link_ac_type_link_activate_resources) {
+		_current_link_action_request = 0;
+		mih_user::send_MIH_Link_Actions_request(rsp->id, odtone::mih::link_ac_type_link_deactivate_resources);
+	    }
+	    else { // Ends the scenario
+	      mih_user::send_MIH_Event_Unsubscribe_request();
+	    }
+	}
+#endif // SCENARIO_2
+
+    log_(0, "MIH_Link_Actions.confirm - End\n");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::send_MIH_Link_Configure_Thresholds_request(odtone::mih::message& msg, const boost::system::error_code& ec)
+//-----------------------------------------------------------------------------
+{
+    odtone::mih::message                 m;
+    odtone::mih::threshold               th;
+    std::vector<odtone::mih::threshold>  thl;
+    odtone::mih::link_tuple_id           lti;
+    odtone::mih::l2_3gpp_addr            local_l2_3gpp_addr;
+    //List of the link threshold parameters
+    odtone::mih::link_cfg_param_list     lcpl;
+    odtone::mih::link_cfg_param          lcp;
+    odtone::mih::link_param_lte          lp;
+    //odtone::mih::link_param_gen          lp;
+
+    odtone::mih::link_param_type typr;
+
+    log_(0,"");
+    log_(0, "send_MIH_Link_Configure_Thresholds_request - Begin");
+
+    //link_tuple_id
+    lti.type = rcv_link_id.type;
+    lti.addr = rcv_link_id.addr;
+
+    //local_l2_3gpp_addr = boost::get<odtone::mih::l2_3gpp_addr>(lti.addr);
+
+
+    //link_param_gen_data_rate = 0,           /**< Data rate.         */
+    //link_param_gen_signal_strength = 1,     /**< Signal strength.   */
+    //link_param_gen_sinr = 2,                /**< SINR.              */
+    //link_param_gen_throughput = 3,          /**< Throughput.        */
+    //link_param_gen_packet_error_rate = 4,   /**< Packet error rate. */
+    //lp = odtone::mih::link_param_lte_bandwidth;
+    lp = odtone::mih::link_param_lte_rsrp;
+    lcp.type = lp;
+
+    link_measures_request = 0;
+    if ( link_measures_request ==0){
+        // Set Timer Interval (in ms)
+        lcp.timer_interval = 3000;
+        //th_action_normal = 0,   /**< Set normal threshold.      */
+        //th_action_one_shot = 1, /**< Set one-shot threshold.    */
+        //th_action_cancel = 2    /**< Cancel threshold.          */
+        lcp.action = odtone::mih::th_action_normal;
+        link_measures_request = 1;
+    } else if ( link_measures_request==1){
+        // Set Timer Interval (in ms)
+        lcp.timer_interval = 0;
+        lcp.action = odtone::mih::th_action_cancel;
+        link_measures_request = 0;
+    }
+
+    //above_threshold = 0,    /**< Above threshold.   */
+    //below_threshold = 1,    /**< Below threshold.   */
+    th.threshold_val = -105;
+    th.threshold_x_dir = odtone::mih::threshold::above_threshold;
+
+    thl.push_back(th);
+    lcp.threshold_list = thl;
+    lcpl.push_back(lcp);
+
+    m <<  odtone::mih::request(odtone::mih::request::link_configure_thresholds)
+          & odtone::mih::tlv_link_identifier(lti)
+          & odtone::mih::tlv_link_cfg_param_list(lcpl);
+
+    m.destination(msg.source());
+
+    log_(0, "[MSC_MSG]["+getTimeStamp4Log()+"]["+ _mihuserid.to_string() +"][--- MIH_Link_Configure_Thresholds.request\\nlink="+
+                // link_tupple_id2string(lti).c_str() +
+                link_id2string(lti).c_str()+
+                 " --->]["+_mihfid.to_string()+"]\n");
+
+    _mihf.async_send(m, boost::bind(&mih_user::event_handler, this, _1, _2));
+
+    log_(0, "  - LINK_TUPLE_ID - Link identifier:  ", link_id2string(lti).c_str());
+
+    log_(0, "\t- LINK CFG PARAM LIST - Length: ", lcpl.size());
+
+    //if(lp == odtone::mih::link_param_gen_data_rate)       {log_(0, "\t  Generic link parameter DATA RATE ");}
+    //if(lp == odtone::mih::link_param_gen_signal_strength) {log_(0, "\t  Generic link parameter SIGNAL STRENGTH");}
+    //if(lp == odtone::mih::link_param_gen_sinr)            {log_(0, "\t   Generic link parameter SINR");}
+    //if(lp == odtone::mih::link_param_gen_throughput)      {log_(0, "\t  Generic link parameter THROUGHPUT");}
+    //if(lp == odtone::mih::link_param_lte_bandwidth)       {log_(0, "\t  LTE link parameter BANDWIDTH");}
+    if(lp == odtone::mih::link_param_lte_rsrp)       {log_(0, "\t  LTE link parameter LTE RSRP");}
+
+    log_(0, "\t- TIMER INTERVAL - Value: ", lcp.timer_interval);
+
+    if(lcp.action == odtone::mih::th_action_normal)   {log_(0, "\t  Normal Threshold");}
+    if(lcp.action == odtone::mih::th_action_one_shot) {log_(0, "\t  One Shot Threshold");}
+    if(lcp.action == odtone::mih::th_action_cancel)   {log_(0, "\t  Threshold to be canceled");}
+
+    log_(0, "\t  Threshold value: ", th.threshold_val);
+
+    if(th.threshold_x_dir == odtone::mih::threshold::below_threshold) {log_(0, "\t  Threshold direction BELOW");}
+    if(th.threshold_x_dir == odtone::mih::threshold::above_threshold) {log_(0, "\t  Threshold direction ABOVE");}
+
+    log_(0, "send_MIH_Link_Configure_Thresholds_request - End");
+}
+
+//-----------------------------------------------------------------------------
+void mih_user::receive_MIH_Link_Configure_Thresholds_confirm(odtone::mih::message& msg, const boost::system::error_code& ec)
+//-----------------------------------------------------------------------------
+{
+    log_(0, "");
+    log_(0, "receive_MIH_Link_Configure_Thresholds_confirm - Begin");
+
+    // T odtone::uint iter;
+    // T odtone::mih::status st;
+
+    //boost::optional<odtone::mih::link_cfg_status_list> lcsl;
+    // Todtone::mih::link_cfg_status_list lcsl;
+    // Todtone::mih::link_cfg_status lcp;
+    //odtone::mih::link_param_gen lp;
+
+    // T odtone::mih::link_tuple_id lti;
+
+    //msg >> odtone::mih::confirm()
+    //    & odtone::mih::tlv_status(st)
+    //    & odtone::mih::tlv_link_identifier(lti)
+    //    & odtone::mih::tlv_link_cfg_status_list(lcsl);
+
+
+    log_(0, "receive_MIH_Link_Configure_Thresholds_confirm - End");
+    log_(0,"");
+}
+
+//-----------------------------------------------------------------------------
+int main(int argc, char** argv)
+//-----------------------------------------------------------------------------
+{
+    odtone::setup_crash_handler();
+
+    try {
+        boost::asio::io_service ios;
+
+        // declare MIH Usr available options
+        po::options_description desc(odtone::mih::octet_string("MIH Usr Configuration"));
+        desc.add_options()
+            ("help", "Display configuration options")
+            (odtone::sap::kConf_File, po::value<std::string>()->default_value("ue_lte_user.conf"), "Configuration file")
+            (odtone::sap::kConf_Receive_Buffer_Len, po::value<uint>()->default_value(4096),        "Receive buffer length")
+            (odtone::sap::kConf_Port, po::value<ushort>()->default_value(1235),                    "Listening port")
+            (odtone::sap::kConf_MIH_SAP_id, po::value<std::string>()->default_value("user"),       "MIH-User ID")
+            (kConf_MIH_Commands, po::value<std::string>()->default_value(""),                      "MIH-User supported commands")
+            (odtone::sap::kConf_MIHF_Ip, po::value<std::string>()->default_value("127.0.0.1"),     "Local MIHF IP address")
+            (odtone::sap::kConf_MIHF_Local_Port, po::value<ushort>()->default_value(1025),         "Local MIHF communication port")
+            (odtone::sap::kConf_MIH_SAP_dest, po::value<std::string>()->default_value("mihf2_ue"), "MIHF destination");
+
+        odtone::mih::config cfg(desc);
+        cfg.parse(argc, argv, odtone::sap::kConf_File);
+
+        if (cfg.help()) {
+            std::cerr << desc << std::endl;
+            return EXIT_SUCCESS;
+        }
+
+        mih_user usr(cfg, ios);
+
+        ios.run();
+
+    } catch(std::exception& e) {
+        log_(0, "exception: ", e.what());
+    }
+}
+
+// EOF ////////////////////////////////////////////////////////////////////////
+
-- 
GitLab