diff --git a/openbsc/include/openbsc/gsm_04_80.h b/openbsc/include/openbsc/gsm_04_80.h
index 0a60652..1f87bd4 100644
--- a/openbsc/include/openbsc/gsm_04_80.h
+++ b/openbsc/include/openbsc/gsm_04_80.h
@@ -10,6 +10,9 @@ struct gsm_subscriber_connection;
 int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,
 			       const struct msgb *in_msg, const char* response_text, 
 			       const struct ussd_request *req);
+int gsm0480_send_ussd_facility(struct gsm_subscriber_connection *conn,
+			       const struct msgb *in_msg, const char* response_text, 
+			       const struct ussd_request *req);
 int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
 			     const struct msgb *msg, 
 			     const struct ussd_request *request);
diff --git a/openbsc/src/libmsc/gsm_04_80.c b/openbsc/src/libmsc/gsm_04_80.c
index 39738a5..5319e58 100644
--- a/openbsc/src/libmsc/gsm_04_80.c
+++ b/openbsc/src/libmsc/gsm_04_80.c
@@ -48,6 +48,16 @@ static inline unsigned char *msgb_wrap_with_TL(struct msgb *msgb, uint8_t tag)
 	return data;
 }
 
+
+/* ADDED BY MAICON KIST */
+static inline unsigned char *msgb_wrap_with_L(struct msgb *msgb)
+{
+	uint8_t *data = msgb_push(msgb, 1);
+
+	data[0] = msgb->len - 1;
+	return data;
+}
+
 static inline unsigned char *msgb_push_TLV1(struct msgb *msgb, uint8_t tag,
 					    uint8_t value)
 {
@@ -109,6 +119,57 @@ int gsm0480_send_ussd_response(struct gsm_subscriber_connection *conn,
 	return gsm0808_submit_dtap(conn, msg, 0, 0);
 }
 
+
+int gsm0480_send_ussd_facility(struct gsm_subscriber_connection *conn,
+			       const struct msgb *in_msg, const char *response_text,
+			       const struct ussd_request *req)
+{
+	struct msgb *msg = gsm48_msgb_alloc();
+	struct gsm48_hdr *gh;
+	uint8_t *ptr8;
+	int response_len;
+
+	/* First put the payload text into the message */
+	ptr8 = msgb_put(msg, 0);
+	response_len = gsm_7bit_encode(ptr8, response_text);
+	msgb_put(msg, response_len);
+
+	/* Then wrap it as an Octet String */
+	msgb_wrap_with_TL(msg, ASN1_OCTET_STRING_TAG);
+
+	/* Pre-pend the DCS octet string */
+	msgb_push_TLV1(msg, ASN1_OCTET_STRING_TAG, 0x0F);
+
+	/* Then wrap these as a Sequence */
+	msgb_wrap_with_TL(msg, GSM_0480_SEQUENCE_TAG);
+
+	/* Pre-pend the operation code */
+	msgb_push_TLV1(msg, GSM0480_OPERATION_CODE,
+			GSM0480_OP_CODE_USS_REQUEST);
+
+	/* Wrap the operation code and IA5 string as a sequence */
+	//msgb_wrap_with_TL(msg, GSM_0480_SEQUENCE_TAG);
+
+	/* Pre-pend the invoke ID */
+	msgb_push_TLV1(msg, GSM0480_COMPIDTAG_INVOKE_ID, req->invoke_id);
+
+	/* Wrap this up as a Invoke component */
+	msgb_wrap_with_TL(msg, GSM0480_CTYPE_INVOKE);
+
+	/* Wrap the component in a Facility message */
+	msgb_wrap_with_L(msg);
+
+	/* And finally pre-pend the L3 header */
+	gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));
+	gh->proto_discr = GSM48_PDISC_NC_SS | req->transaction_id
+					| (1<<7);  /* TI direction = 1 */
+	gh->msg_type = GSM0480_MTYPE_FACILITY;
+
+	return gsm0808_submit_dtap(conn, msg, 0, 0);
+}
+
+
+
 int gsm0480_send_ussd_reject(struct gsm_subscriber_connection *conn,
 			     const struct msgb *in_msg,
 			     const struct ussd_request *req)
diff --git a/openbsc/src/libmsc/osmo_msc.c b/openbsc/src/libmsc/osmo_msc.c
index 31b72b9..f4260d6 100644
--- a/openbsc/src/libmsc/osmo_msc.c
+++ b/openbsc/src/libmsc/osmo_msc.c
@@ -143,6 +143,7 @@ struct bsc_api *msc_bsc_api() {
 void msc_release_connection(struct gsm_subscriber_connection *conn)
 {
 	/* skip when we are in release, e.g. due an error */
+	DEBUGP(DMM, "verifying connection\n");
 	if (conn->in_release)
 		return;
 
@@ -167,6 +168,9 @@ void msc_release_connection(struct gsm_subscriber_connection *conn)
 	if (conn->expire_timer_stopped)
 		subscr_update_expire_lu(conn->subscr, conn->bts);
 
+
+	DEBUGP(DMM, "connection closed\n");
+
 	conn->in_release = 1;
 	gsm0808_clear(conn);
 	if (conn->put_channel) {
diff --git a/openbsc/src/libmsc/ussd.c b/openbsc/src/libmsc/ussd.c
index 76ee101..f723e2c 100644
--- a/openbsc/src/libmsc/ussd.c
+++ b/openbsc/src/libmsc/ussd.c
@@ -38,7 +38,11 @@
 const char USSD_TEXT_OWN_NUMBER[] = "*#100#";
 
 /* Forward declarations of network-specific handler functions */
-static int send_own_number(struct gsm_subscriber_connection *conn, const struct msgb *msg, const struct ussd_request *req);
+static int send_own_number(struct gsm_subscriber_connection *conn, const struct msgb *msg, struct ussd_request *req);
+
+static int dcg_hello(struct gsm_subscriber_connection *conn, const struct msgb *msg, struct ussd_request *req);
+
+static int dcg_menu(struct gsm_subscriber_connection *conn, const struct msgb *msg, struct ussd_request *req);
 
 
 /* Entrypoint - handler function common to all mobile-originated USSDs */
@@ -54,9 +58,33 @@ int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg)
 	if (req.text[0] == 0xFF)  /* Release-Complete */
 		return 0;
 
-	if (!strcmp(USSD_TEXT_OWN_NUMBER, (const char *)req.text)) {
-		DEBUGP(DMM, "USSD: Own number requested\n");
-		rc = send_own_number(conn, msg, &req);
+	/* USSD numbers and functions */
+	struct  ussd_application
+	{
+		const char ussd_number[10];
+		int (*ussd_func)(struct gsm_subscriber_connection *conn, struct msgb *msg, struct ussd_request *req);
+	} ussd_arr []  =
+   	{
+		{ "*#100#",  &send_own_number }, /* hello_dcg */
+		{ "*#2#",    &dcg_menu },   /* dcg interactive menu */
+		{ "*#1#",    &dcg_hello },   /* send number */
+	} ;
+
+	/* Search for ussd valid number */
+	int i = 0;
+	DEBUGP(DMM, "req str:  %s\n", req.text);
+	for (; i < sizeof(ussd_arr)/sizeof(struct ussd_application); ++i)
+	{
+		if (!strcmp(ussd_arr[i].ussd_number, (const char *)req.text))
+		{
+			DEBUGP(DMM, "Handling USSD %s\n", ussd_arr[i].ussd_number);
+			break;
+		}
+	}
+
+	if (i < sizeof(ussd_arr)/sizeof(struct ussd_application))
+	{
+		rc = ussd_arr[i].ussd_func(conn, msg, &req );
 	} else {
 		DEBUGP(DMM, "Unhandled USSD %s\n", req.text);
 		rc = gsm0480_send_ussd_reject(conn, msg, &req);
@@ -68,7 +96,7 @@ int handle_rcv_ussd(struct gsm_subscriber_connection *conn, struct msgb *msg)
 }
 
 /* A network-specific handler function */
-static int send_own_number(struct gsm_subscriber_connection *conn, const struct msgb *msg, const struct ussd_request *req)
+static int send_own_number(struct gsm_subscriber_connection *conn, const struct msgb *msg, struct ussd_request *req)
 {
 	char *own_number = conn->subscr->extension;
 	char response_string[GSM_EXTENSION_LENGTH + 20];
@@ -77,3 +105,16 @@ static int send_own_number(struct gsm_subscriber_connection *conn, const struct
 	snprintf(response_string, sizeof(response_string), "Your extension is %s\r", own_number);
 	return gsm0480_send_ussd_response(conn, msg, response_string, req);
 }
+
+
+static int dcg_hello(struct gsm_subscriber_connection *conn, const struct msgb *msg, struct ussd_request *req)
+{
+	const char response_string[] = "Saudacoes do DCG\n";
+	return gsm0480_send_ussd_response(conn, msg, response_string, req);
+}
+
+static int dcg_menu(struct gsm_subscriber_connection *conn, const struct msgb *msg, struct ussd_request *req)
+{
+	const char response_string[] = "Menu do DCG\n";
+	return gsm0480_send_ussd_facility(conn, msg, response_string, req);
+}
