From 642b1a2e6d8a2679f3ee2573852f5c4d9633dcd7 Mon Sep 17 00:00:00 2001
From: kapil <kgupta@sangoma.com>
Date: Thu, 5 Jul 2012 10:39:36 +0530
Subject: [PATCH] adding code for sending termination service change and
 respective CLI command

---
 .../mod_media_gateway/media_gateway_cli.c     |  22 +
 .../media_gateway_cmd_handler.c               | 114 +++-
 .../mod_media_gateway/media_gateway_stack.h   |  20 +-
 .../media_gateway_stack_alarms.c              |   3 +
 .../mod_media_gateway/media_gateway_utils.c   | 511 ++++++++++++------
 5 files changed, 506 insertions(+), 164 deletions(-)

diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_cli.c b/src/mod/endpoints/mod_media_gateway/media_gateway_cli.c
index e21fc9d3af..9d1c27e007 100644
--- a/src/mod/endpoints/mod_media_gateway/media_gateway_cli.c
+++ b/src/mod/endpoints/mod_media_gateway/media_gateway_cli.c
@@ -94,6 +94,28 @@ switch_status_t mg_process_cli_cmd(const char *cmd, switch_stream_handle_t *stre
 			} else {
 				stream->write_function(stream, "-ERR No such profile\n");
 			}
+/**********************************************************************************/
+		}else if(!strcmp(argv[2], "send")) {
+/**********************************************************************************/
+			/* mg profile <profile-name> send sc <term-id> <method> <reason>*/
+			printf("count = %d \n",argc);
+			if(argc < 7){
+				goto usage;
+			}
+			if(zstr(argv[3]) || zstr(argv[4]) || zstr(argv[5]) || zstr(argv[6])){
+				goto usage;
+			}
+
+			if (profile) {
+				printf("Input to Send Service Change command : "
+						"Profile Name[%s], term-id[%s] method[%s] reason[%s] \n",
+						profile->name, argv[4], argv[5], argv[6]);
+
+				megaco_profile_release(profile);
+				mg_send_service_change(profile->idx, argv[4], atoi(argv[5]), atoi(argv[6]));
+			} else {
+				stream->write_function(stream, "-ERR No such profile\n");
+			}
 /**********************************************************************************/
 		}else {
 /**********************************************************************************/
diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c b/src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c
index 696e7579f8..b4e8d04442 100644
--- a/src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c
+++ b/src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c
@@ -9,6 +9,15 @@
 #include "mod_media_gateway.h"
 #include "media_gateway_stack.h"
 
+U32 outgoing_txn_id;
+
+/*****************************************************************************************************************************/
+const char *mg_service_change_reason[] = {
+	"\"NOT USED\"",
+	"\"900 ServiceRestored\"",
+	"\"905 Termination taken out of service\"",
+	0
+};
 
 /*****************************************************************************************************************************/
 
@@ -134,7 +143,7 @@ switch_status_t mg_send_add_rsp(SuId suId, MgMgcoCommand *req)
 #else
 	termId = &(cmd.u.mgCmdRsp[0]->u.add.termId);
 #endif
-	mg_fill_mgco_termid(termId, (CONSTANT U8*)"term1",&req->u.mgCmdRsp[0]->memCp);
+	/*mg_fill_mgco_termid(termId, (char*)"term1",&req->u.mgCmdRsp[0]->memCp);*/
 
 	/* We will always send one command at a time..*/
 	cmd.cmdStatus.pres = PRSNT_NODEF;
@@ -197,7 +206,7 @@ switch_status_t mg_send_end_of_axn(SuId suId, MgMgcoTransId* transId, MgMgcoCont
 
 switch_status_t mg_build_mgco_err_request(MgMgcoInd  **errcmd,U32  trans_id, MgMgcoContextId   *ctxt_id, U32  err, MgStr  *errTxt)
 {
-	MgMgcoInd     *mgErr;   
+	MgMgcoInd     *mgErr = NULL;   
 	S16            ret;
 
 	mgErr = NULLP;
@@ -584,6 +593,8 @@ switch_status_t mg_send_heartbeat_audit_rsp( SuId suId, MgMgcoCommand *auditReq)
 }
 
 /*****************************************************************************************************************************/
+#if 0
+/* Kapil - Not using any more */
 switch_status_t handle_media_audit( SuId suId, MgMgcoCommand *auditReq)
 {
 	switch_status_t  ret;
@@ -788,7 +799,10 @@ switch_status_t handle_pkg_audit( SuId suId, MgMgcoCommand *auditReq)
 
 
 }
+#endif
 /*****************************************************************************************************************************/
+#if 0
+/* Kapil - Not using any more */
 switch_status_t mg_send_audit_rsp(SuId suId, MgMgcoCommand *req)
 {
 	MgMgcoCommand  cmd;
@@ -858,6 +872,7 @@ switch_status_t mg_send_audit_rsp(SuId suId, MgMgcoCommand *req)
 
 	return ret;
 }
+#endif
 
 /*****************************************************************************************************************************/
 switch_status_t mg_send_modify_rsp(SuId suId, MgMgcoCommand *req)
@@ -897,7 +912,7 @@ switch_status_t mg_send_modify_rsp(SuId suId, MgMgcoCommand *req)
 #else
 	termId = &(cmd.u.mgCmdRsp[0]->u.mod.termId);
 #endif
-	mg_fill_mgco_termid(termId, (CONSTANT U8*)"term1",&req->u.mgCmdRsp[0]->memCp);
+	/*mg_fill_mgco_termid(termId, (char*)"term1",&req->u.mgCmdRsp[0]->memCp);*/
 
 	/* We will always send one command at a time..*/
 	cmd.cmdStatus.pres = PRSNT_NODEF;
@@ -958,7 +973,7 @@ switch_status_t mg_send_subtract_rsp(SuId suId, MgMgcoCommand *req)
 #else
 	termId = &(cmd.u.mgCmdRsp[0]->u.sub.termId);
 #endif
-	mg_fill_mgco_termid(termId, (CONSTANT U8*)"term1",&req->u.mgCmdRsp[0]->memCp);
+	/*mg_fill_mgco_termid(termId, (char *)"term1",&req->u.mgCmdRsp[0]->memCp);*/
 
 	/* We will always send one command at a time..*/
 	cmd.cmdStatus.pres = PRSNT_NODEF;
@@ -979,3 +994,94 @@ switch_status_t mg_send_subtract_rsp(SuId suId, MgMgcoCommand *req)
 
 	return ret;
 }
+/*****************************************************************************************************************************/
+U32 get_txn_id(){
+	outgoing_txn_id++;
+	return outgoing_txn_id;
+}
+/*****************************************************************************************************************************/
+/* Note : API to send Service Change */
+/* INPUT : 
+*	method 			- Service change method type (can be MGT_SVCCHGMETH_RESTART/MGT_SVCCHGMETH_FORCED (please refer to sng_ss7/cm/mgt.h for more values))
+*	MgServiceChangeReason_e - Service Change reason 	
+*	SuId 			- Service User ID for MG SAP - it will be same like mg_profile_t->idx (refer to media_gateway_xml.c->mg_sap_id)
+*	term_name 		- String format defined termination name
+*/
+switch_status_t mg_send_service_change(SuId suId, const char* term_name, uint8_t method, MgServiceChangeReason_e reason)
+{
+	MgMgcoSvcChgPar srvPar;
+	MgMgcoTermId*   termId;
+	switch_status_t ret;
+	MgMgcoCommand   request;
+	MgMgcoSvcChgReq      *svc;
+
+	MG_ZERO(&srvPar, sizeof(MgMgcoSvcChgPar));
+	MG_ZERO(&request, sizeof(request));
+
+	
+
+	if(SWITCH_STATUS_FALSE == (ret = mg_create_mgco_command(&request, CH_CMD_TYPE_REQ, MGT_SVCCHG))){
+		goto err;
+	}
+
+	/*fill txn id */
+	request.transId.pres = PRSNT_NODEF;
+	request.transId.val  = get_txn_id();
+
+	request.contextId.type.pres = PRSNT_NODEF;
+	request.contextId.type.val = MGT_CXTID_NULL;
+
+#if 0
+	/* TODO - fill of below fields */
+#ifdef GCP_MGCO
+#ifdef GCP_VER_2_1
+	MgMgcoSegNum          segNum;
+	MgMgcoSegCmpl         segCmpl;
+#endif
+#endif  /* GCP_MGCO */
+#endif
+	request.cmdStatus.pres = PRSNT_NODEF;
+	request.cmdStatus.val = CH_CMD_STATUS_END_OF_TXN;
+
+	request.cmdType.pres = PRSNT_NODEF;
+	request.cmdType.val  = CH_CMD_TYPE_REQ;
+
+	svc = &request.u.mgCmdReq[0]->cmd.u.svc;
+
+	if(SWITCH_STATUS_FALSE == (ret = mg_fill_svc_change(&svc->parm, method, mg_service_change_reason[reason]))){
+		return ret;
+	}
+
+	/*mgUtlCpyMgMgcoSvcChgPar(&svc->parm, &srvPar, &request.u.mgCmdReq[0]->memCp);*/
+
+	printf("reason[%p = %s], len[%d]\n",svc->parm.reason.val, svc->parm.reason.val, svc->parm.reason.len);
+
+
+	if (mgUtlGrowList((void ***)&svc->termIdLst.terms, sizeof(MgMgcoTermIdLst),
+				&svc->termIdLst.num, &request.u.mgCmdReq[0]->memCp) != ROK)
+	{
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"Grow List failed\n");
+		return SWITCH_STATUS_FALSE;
+	}
+
+#ifdef GCP_VER_2_1
+	termId = svc->termIdLst.terms[0];
+#else
+	termId = &(svc->termId);
+#endif
+
+
+	mg_fill_mgco_termid(termId, (char*)term_name ,strlen(term_name), &request.u.mgCmdReq[0]->memCp);
+
+
+	printf("reason[%p = %s], len[%d]\n",svc->parm.reason.val, svc->parm.reason.val, svc->parm.reason.len);
+
+	sng_mgco_send_cmd(suId, &request);
+
+	return SWITCH_STATUS_SUCCESS;
+
+err:
+	mgUtlDelMgMgcoSvcChgPar(&srvPar);
+	return ret;
+}
+/*****************************************************************************************************************************/
diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h b/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h
index fbd598ab3c..a90e6dc2c4 100644
--- a/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h
+++ b/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h
@@ -60,6 +60,13 @@ typedef struct _mgPackage
 
 extern MgPackage_t mg_pkg_list[];
 
+/* Service change Reason  */
+typedef enum { 
+   MG_SVC_REASON_NOTUSED = 0,
+   MG_SVC_REASON_900_RESTORED = 1,
+   MG_SVC_REASON_905_TERM_OOS = 2,
+   MG_SVC_REASON_LAST = 4
+} MgServiceChangeReason_e;
 
 #define MG_TXN_INVALID 0
 
@@ -74,6 +81,12 @@ extern MgPackage_t mg_pkg_list[];
    MG_SET_PRES((tkn).pres);          \
    (tkn).val = _val;                        
 
+#define MG_SET_TKN_VAL_PRES(_tkn, _val, _pres)                       \
+{                                                                   \
+   (_tkn)->val  = _val;                                             \
+   (_tkn)->pres = _pres;                                            \
+}
+
 
 #define MG_MEM_COPY(_dst, _src, _len) \
 	cmMemcpy((U8*) (_dst), (const U8*) (_src), _len)
@@ -126,7 +139,7 @@ switch_status_t mg_stack_alloc_mem( Ptr* _memPtr, Size _memSize );
 MgMgcoMediaDesc* get_default_media_desc(void);
 switch_status_t handle_media_audit( SuId suId, MgMgcoCommand *auditReq);
 switch_status_t mg_send_add_rsp(SuId suId, MgMgcoCommand *req);
-S16 mg_fill_mgco_termid ( MgMgcoTermId  *termId, CONSTANT U8   *str, CmMemListCp   *memCp);
+S16 mg_fill_mgco_termid ( MgMgcoTermId  *termId, char* term_str, int term_len, CmMemListCp   *memCp);
 void mg_util_set_txn_string(MgStr  *errTxt, U32 *txnId);
 switch_status_t mg_build_mgco_err_request(MgMgcoInd  **errcmd,U32  trans_id, MgMgcoContextId   *ctxt_id, U32  err, MgStr  *errTxt);
 switch_status_t mg_send_audit_rsp(SuId suId, MgMgcoCommand *req);
@@ -139,6 +152,11 @@ MgMgcoTermIdLst *mg_get_term_id_list(MgMgcoCommand *cmd);
 switch_status_t handle_pkg_audit( SuId suId, MgMgcoCommand *auditReq);
 switch_status_t mg_build_pkg_desc(MgMgcoPkgsDesc* pkg);
 switch_status_t mg_send_heartbeat_audit_rsp( SuId suId, MgMgcoCommand *auditReq);
+void mg_get_time_stamp(MgMgcoTimeStamp *timeStamp);
+switch_status_t  mg_fill_svc_change(MgMgcoSvcChgPar  *srvPar, uint8_t  method, const char  *reason);
+void mg_fill_null_context(MgMgcoContextId* ctxt);
+switch_status_t mg_send_service_change(SuId suId, const char* term_name, uint8_t method, MgServiceChangeReason_e reason);
+switch_status_t  mg_create_mgco_command(MgMgcoCommand  *cmd, uint8_t apiType, uint8_t cmdType);
 
 
 
diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_stack_alarms.c b/src/mod/endpoints/mod_media_gateway/media_gateway_stack_alarms.c
index fc09a6bea4..5281a7942a 100644
--- a/src/mod/endpoints/mod_media_gateway/media_gateway_stack_alarms.c
+++ b/src/mod/endpoints/mod_media_gateway/media_gateway_stack_alarms.c
@@ -208,6 +208,9 @@ void handle_mg_alarm(Pst *pst, MgMngmt *usta)
 		case LMG_EVENT_PEER_ENABLED:
 			{
 				len = len + sprintf(prBuf+len, "gateway enabled");
+				/* gateway enabled now we can send termination service change */
+				/*TODO - probably we cannt immediate send Service change - we have to find proper place */
+				/*mg_send_service_change(0x01, "A01", MGT_SVCCHGMETH_RESTART,MG_SVC_REASON_900_RESTORED );*/
 				break;
 			}
 		case LMG_EVENT_PEER_DISCOVERED:
diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_utils.c b/src/mod/endpoints/mod_media_gateway/media_gateway_utils.c
index 39f7fb71d2..ed70b74173 100644
--- a/src/mod/endpoints/mod_media_gateway/media_gateway_utils.c
+++ b/src/mod/endpoints/mod_media_gateway/media_gateway_utils.c
@@ -80,45 +80,65 @@ switch_status_t mg_stack_free_mem(void* msg)
 
 /*****************************************************************************************************************************/
 
-S16 mg_fill_mgco_termid ( MgMgcoTermId  *termId, CONSTANT U8   *str, CmMemListCp   *memCp)
+S16 mg_fill_mgco_termid ( MgMgcoTermId  *termId, char* term_str, int term_len, CmMemListCp   *memCp)
 {
 #ifdef GCP_ASN       
-   Size              size;
+	Size              size;
 #endif
-   S16               ret = ROK;
+	S16               ret = ROK;
 
-   termId->name.pres.pres = PRSNT_NODEF;
-   /* mg011.105: Bug fixes */
-   termId->name.lcl.pres = PRSNT_NODEF;
-   termId->name.lcl.len = cmStrlen((CONSTANT U8*)str);
-   MG_GETMEM(termId->name.lcl.val, termId->name.lcl.len, memCp, ret);
-   if( ret != ROK)
-      RETVALUE(ret);          
+	termId->type.pres = PRSNT_NODEF;
+	termId->type.val  = MGT_TERMID_OTHER;
 
-   cmMemcpy((U8*)(termId->name.lcl.val), (CONSTANT U8*)str,termId->name.lcl.len);
+	termId->name.dom.pres = NOTPRSNT;  
+	termId->name.dom.len = 0x00;  
 
-#ifdef GCP_ASN          
-   /* Remove comment to fill other term ID 
-   termId->wildcard.num.pres = NOTPRSNT; */
-   /* Remove comment to fill wilcard term ID */
-   termId->wildcard.num.pres = PRSNT_NODEF;    
-   termId->wildcard.num.val = 1;
-   size = ((sizeof(MgMgcoWildcardField*)));
-   MG_GETMEM((termId->wildcard.wildcard),size,memCp, ret);
-   if( ret != ROK)
-      RETVALUE(ret);
+	termId->name.pres.pres = PRSNT_NODEF;
+	termId->name.lcl.pres = PRSNT_NODEF;
+	termId->name.lcl.len = term_len;
+	/*MG_GETMEM(termId->name.lcl.val, termId->name.lcl.len , memCp, ret);*/
+	ret = mg_stack_alloc_mem((Ptr*)&termId->name.lcl.val,term_len);
 
-   MG_GETMEM( ((termId->wildcard.wildcard)[0]),sizeof(MgMgcoWildcardField),
-                  memCp, ret);
-   if( ret != ROK)
-      RETVALUE(ret);
+	printf("termId->name.lcl.val[%p]\n",termId->name.lcl.val);
 
-   termId->wildcard.wildcard[0]->pres = PRSNT_NODEF;
-   termId->wildcard.wildcard[0]->len = 1;
-   termId->wildcard.wildcard[0]->val[0] = 0x55;
+	if( ret != ROK)
+		RETVALUE(ret);          
+
+	/*cmMemcpy((U8*)(termId->name.lcl.val), (CONSTANT U8*)term_str,termId->name.lcl.len);*/
+	strncpy((char*)(termId->name.lcl.val), term_str, termId->name.lcl.len);
+	termId->name.lcl.val[termId->name.lcl.len] = '\0';
+
+	printf("mg_fill_mgco_termid: name.lcl.val[%s], len[%d], term_str[%s], term_len[%d]\n",termId->name.lcl.val, termId->name.lcl.len, term_str,term_len);
+	      
+
+#ifdef GCP_ASN
+	if((termId->type.val == MGT_TERMID_ALL) ||
+			(termId->type.val == MGT_TERMID_CHOOSE)){
+		/* Remove comment to fill other term ID 
+		   termId->wildcard.num.pres = NOTPRSNT; */ 
+		/* Remove comment to fill wilcard term ID */
+		termId->wildcard.num.pres = PRSNT_NODEF;
+		termId->wildcard.num.val = 1;
+		size = ((sizeof(MgMgcoWildcardField*)));
+		MG_GETMEM((termId->wildcard.wildcard),size,memCp, ret);
+		if( ret != ROK)
+			RETVALUE(ret);
+
+		MG_GETMEM( ((termId->wildcard.wildcard)[0]),sizeof(MgMgcoWildcardField),
+				memCp, ret);
+		if( ret != ROK)
+			RETVALUE(ret);
+
+		termId->wildcard.wildcard[0]->pres = PRSNT_NODEF;
+		termId->wildcard.wildcard[0]->len = 1;
+		termId->wildcard.wildcard[0]->val[0] = 0x55;
+
+	}else{
+		   termId->wildcard.num.pres = NOTPRSNT;
+	}
 #endif /* GCP_ASN */
 
-   RETVALUE(ROK);
+	RETVALUE(ROK);
 }
 
 /*****************************************************************************************************************************/
@@ -270,166 +290,166 @@ MgMgcoTermIdLst *mg_get_term_id_list(MgMgcoCommand *cmd)
 
 void mg_util_set_txn_string(MgStr  *errTxt, U32 *txnId)
 {
-   MG_ZERO(errTxt->val, sizeof(errTxt->val));
-   errTxt->len = 0;
+	MG_ZERO(errTxt->val, sizeof(errTxt->val));
+	errTxt->len = 0;
 
-   errTxt->val[errTxt->len] = '\"';
-   errTxt->len += 1;
+	errTxt->val[errTxt->len] = '\"';
+	errTxt->len += 1;
 
-   if (MG_TXN_INVALID == txnId )
-   {
-      MG_MEM_COPY((&errTxt->val[errTxt->len]), "TransactionId=0", 15);
-      errTxt->len += 15;
-   }           
+	if (MG_TXN_INVALID == txnId )
+	{
+		MG_MEM_COPY((&errTxt->val[errTxt->len]), "TransactionId=0", 15);
+		errTxt->len += 15;
+	}           
 
-   errTxt->val[errTxt->len] = '\"';
-   errTxt->len += 1;
+	errTxt->val[errTxt->len] = '\"';
+	errTxt->len += 1;
 
-     switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s:" 
-                     "info, error-text is: %s\n", __PRETTY_FUNCTION__,errTxt->val);
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s:" 
+			"info, error-text is: %s\n", __PRETTY_FUNCTION__,errTxt->val);
 
 }
 
 /*****************************************************************************************************************************/
 void mg_util_set_ctxt_string ( MgStr  *errTxt, MgMgcoContextId     *ctxtId)
 {
-   MG_ZERO((errTxt->val), sizeof(errTxt->val));
-   errTxt->len = 0;
-   if(ctxtId->type.pres != NOTPRSNT)
-   {
-      errTxt->val[errTxt->len] = '\"';
-      errTxt->len += 1;
-      if(ctxtId->type.val == MGT_CXTID_NULL)
-      {
-         errTxt->val[errTxt->len] = '-';
-         errTxt->len    += 1;
-      }
-      else if(ctxtId->type.val == MGT_CXTID_ALL)
-      {
-         errTxt->val[errTxt->len] = '*';
-         errTxt->len    += 1;
-      }
-      else if(ctxtId->type.val == MGT_CXTID_CHOOSE)
-      {
-         errTxt->val[errTxt->len] = '$';
-         errTxt->len    += 1;
-      }
-      else if((ctxtId->type.val == MGT_CXTID_OTHER) && (ctxtId->val.pres != NOTPRSNT))
-      {
+	MG_ZERO((errTxt->val), sizeof(errTxt->val));
+	errTxt->len = 0;
+	if(ctxtId->type.pres != NOTPRSNT)
+	{
+		errTxt->val[errTxt->len] = '\"';
+		errTxt->len += 1;
+		if(ctxtId->type.val == MGT_CXTID_NULL)
+		{
+			errTxt->val[errTxt->len] = '-';
+			errTxt->len    += 1;
+		}
+		else if(ctxtId->type.val == MGT_CXTID_ALL)
+		{
+			errTxt->val[errTxt->len] = '*';
+			errTxt->len    += 1;
+		}
+		else if(ctxtId->type.val == MGT_CXTID_CHOOSE)
+		{
+			errTxt->val[errTxt->len] = '$';
+			errTxt->len    += 1;
+		}
+		else if((ctxtId->type.val == MGT_CXTID_OTHER) && (ctxtId->val.pres != NOTPRSNT))
+		{
 #ifdef BIT_64
-         sprintf((char*)&errTxt->val[errTxt->len], "%d", ctxtId->val.val);
+			sprintf((char*)&errTxt->val[errTxt->len], "%d", ctxtId->val.val);
 #else
-         sprintf((char*)&errTxt->val[errTxt->len], "%lu", ctxtId->val.val);
+			sprintf((char*)&errTxt->val[errTxt->len], "%lu", ctxtId->val.val);
 #endif
-         errTxt->len += cmStrlen((U8*)(&errTxt->val[errTxt->len]));
-      }
+			errTxt->len += cmStrlen((U8*)(&errTxt->val[errTxt->len]));
+		}
 
-      errTxt->val[errTxt->len] = '\"';
-      errTxt->len += 1;
-   }
-    switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s:" 
-                     "info, error-text is: %s\n", __PRETTY_FUNCTION__,errTxt->val);
+		errTxt->val[errTxt->len] = '\"';
+		errTxt->len += 1;
+	}
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s:" 
+			"info, error-text is: %s\n", __PRETTY_FUNCTION__,errTxt->val);
 }
 
 
 /*****************************************************************************************************************************/
 void mgco_print_sdp(CmSdpInfoSet *sdp)
 {
-    int i;
-    
-    
-    if (sdp->numComp.pres == NOTPRSNT) {
-        return;
-    }
-    
-    for (i = 0; i < sdp->numComp.val; i++) {
-        CmSdpInfo *s = sdp->info[i];
-        int mediaId;
-        
-        if (s->conn.addrType.pres && s->conn.addrType.val == CM_SDP_ADDR_TYPE_IPV4 &&
-            s->conn.netType.type.val == CM_SDP_NET_TYPE_IN &&
-            s->conn.u.ip4.addrType.val == CM_SDP_IPV4_IP_UNI) {
+	int i;
 
-            if (s->conn.u.ip4.addrType.pres) {
-                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Address: %d.%d.%d.%d\n",
-                                   s->conn.u.ip4.u.uniIp.b[0].val,
-                                   s->conn.u.ip4.u.uniIp.b[1].val,
-                                   s->conn.u.ip4.u.uniIp.b[2].val,
-                                   s->conn.u.ip4.u.uniIp.b[3].val);
-            }
-            if (s->attrSet.numComp.pres) {
-                for (mediaId = 0; mediaId < s->attrSet.numComp.val; mediaId++) {
-                    /*CmSdpAttr *a = s->attrSet.attr[mediaId];*/
-                    
-                    
-                }
-            }
 
-            if (s->mediaDescSet.numComp.pres) {
-                for (mediaId = 0; mediaId < s->mediaDescSet.numComp.val; mediaId++) {
-                    CmSdpMediaDesc *desc = s->mediaDescSet.mediaDesc[mediaId];
-                    
-                    if (desc->field.mediaType.val == CM_SDP_MEDIA_AUDIO &&
-                        desc->field.id.type.val ==  CM_SDP_VCID_PORT &&
-                        desc->field.id.u.port.type.val == CM_SDP_PORT_INT &&
-                        desc->field.id.u.port.u.portInt.port.type.val == CM_SDP_SPEC) {
-                        int port = desc->field.id.u.port.u.portInt.port.val.val;
-                        
-                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Port: %d\n", port);
-                        
-                    }
-                }
-            }
-        }
-    }
+	if (sdp->numComp.pres == NOTPRSNT) {
+		return;
+	}
+
+	for (i = 0; i < sdp->numComp.val; i++) {
+		CmSdpInfo *s = sdp->info[i];
+		int mediaId;
+
+		if (s->conn.addrType.pres && s->conn.addrType.val == CM_SDP_ADDR_TYPE_IPV4 &&
+				s->conn.netType.type.val == CM_SDP_NET_TYPE_IN &&
+				s->conn.u.ip4.addrType.val == CM_SDP_IPV4_IP_UNI) {
+
+			if (s->conn.u.ip4.addrType.pres) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Address: %d.%d.%d.%d\n",
+						s->conn.u.ip4.u.uniIp.b[0].val,
+						s->conn.u.ip4.u.uniIp.b[1].val,
+						s->conn.u.ip4.u.uniIp.b[2].val,
+						s->conn.u.ip4.u.uniIp.b[3].val);
+			}
+			if (s->attrSet.numComp.pres) {
+				for (mediaId = 0; mediaId < s->attrSet.numComp.val; mediaId++) {
+					/*CmSdpAttr *a = s->attrSet.attr[mediaId];*/
+
+
+				}
+			}
+
+			if (s->mediaDescSet.numComp.pres) {
+				for (mediaId = 0; mediaId < s->mediaDescSet.numComp.val; mediaId++) {
+					CmSdpMediaDesc *desc = s->mediaDescSet.mediaDesc[mediaId];
+
+					if (desc->field.mediaType.val == CM_SDP_MEDIA_AUDIO &&
+							desc->field.id.type.val ==  CM_SDP_VCID_PORT &&
+							desc->field.id.u.port.type.val == CM_SDP_PORT_INT &&
+							desc->field.id.u.port.u.portInt.port.type.val == CM_SDP_SPEC) {
+						int port = desc->field.id.u.port.u.portInt.port.val.val;
+
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Port: %d\n", port);
+
+					}
+				}
+			}
+		}
+	}
 }
 
 /*****************************************************************************************************************************/
 void mg_util_set_term_string ( MgStr  *errTxt, MgMgcoTermId   *termId) 
 {
-   MG_ZERO((errTxt->val), sizeof(errTxt->val));
-   errTxt->len = 0;
+	MG_ZERO((errTxt->val), sizeof(errTxt->val));
+	errTxt->len = 0;
 
-   if(termId->type.pres != NOTPRSNT)
-   {
-      errTxt->val[errTxt->len] = '\"';
-      errTxt->len += 1;
+	if(termId->type.pres != NOTPRSNT)
+	{
+		errTxt->val[errTxt->len] = '\"';
+		errTxt->len += 1;
 
-      if(termId->type.val == MGT_TERMID_ROOT)
-      {
-          MG_MEM_COPY((&errTxt->val[errTxt->len]), "ROOT", 4);
-          errTxt->len += 4;
-      }
-      else if(termId->type.val == MGT_TERMID_ALL)
-      {
-         errTxt->val[errTxt->len] = '*';
-         errTxt->len    += 1;
-      }
-      else if(termId->type.val == MGT_TERMID_CHOOSE)
-      {
-         errTxt->val[errTxt->len] = '$';
-         errTxt->len    += 1;
-      }
-      else if((termId->type.val == MGT_TERMID_OTHER) && (termId->name.pres.pres != NOTPRSNT))
-      {
-         if(termId->name.lcl.pres != NOTPRSNT)
-         {
-            MG_MEM_COPY(&(errTxt->val[errTxt->len]), termId->name.lcl.val, sizeof(U8) * termId->name.lcl.len);
-            errTxt->len += termId->name.lcl.len;
-         }
-         if(termId->name.dom.pres != NOTPRSNT)
-         {
-            MG_MEM_COPY(&(errTxt->val[errTxt->len]),
-                  termId->name.dom.val, sizeof(U8) * termId->name.dom.len);
-            errTxt->len += termId->name.dom.len;
-         }
-      }
-      errTxt->val[errTxt->len] = '\"';
-      errTxt->len += 1;
-   }
+		if(termId->type.val == MGT_TERMID_ROOT)
+		{
+			MG_MEM_COPY((&errTxt->val[errTxt->len]), "ROOT", 4);
+			errTxt->len += 4;
+		}
+		else if(termId->type.val == MGT_TERMID_ALL)
+		{
+			errTxt->val[errTxt->len] = '*';
+			errTxt->len    += 1;
+		}
+		else if(termId->type.val == MGT_TERMID_CHOOSE)
+		{
+			errTxt->val[errTxt->len] = '$';
+			errTxt->len    += 1;
+		}
+		else if((termId->type.val == MGT_TERMID_OTHER) && (termId->name.pres.pres != NOTPRSNT))
+		{
+			if(termId->name.lcl.pres != NOTPRSNT)
+			{
+				MG_MEM_COPY(&(errTxt->val[errTxt->len]), termId->name.lcl.val, sizeof(U8) * termId->name.lcl.len);
+				errTxt->len += termId->name.lcl.len;
+			}
+			if(termId->name.dom.pres != NOTPRSNT)
+			{
+				MG_MEM_COPY(&(errTxt->val[errTxt->len]),
+						termId->name.dom.val, sizeof(U8) * termId->name.dom.len);
+				errTxt->len += termId->name.dom.len;
+			}
+		}
+		errTxt->val[errTxt->len] = '\"';
+		errTxt->len += 1;
+	}
 
-     switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s:" 
-                     "info, error-text is: %s\n", __PRETTY_FUNCTION__,errTxt->val);
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s:" 
+			"info, error-text is: %s\n", __PRETTY_FUNCTION__,errTxt->val);
 }
 /*****************************************************************************************************************************/
 MgMgcoMediaDesc* get_default_media_desc()
@@ -495,3 +515,176 @@ MgMgcoMediaDesc* get_default_media_desc()
 	return media;
 }
 /*****************************************************************************************************************************/
+
+switch_status_t  mg_fill_svc_change(MgMgcoSvcChgPar  *srvPar, uint8_t  method, const char  *reason)
+{
+	MG_SET_TKN_VAL_PRES(&srvPar->pres, 0, PRSNT_NODEF);
+	MG_SET_TKN_VAL_PRES(&srvPar->meth.pres, 0, PRSNT_NODEF);
+	MG_SET_TKN_VAL_PRES(&srvPar->meth.type, method, PRSNT_NODEF);
+
+	/* Set the reason */
+	srvPar->reason.pres = PRSNT_NODEF;
+	srvPar->reason.len  = cmStrlen((const U8 *)reason);
+
+	mg_stack_alloc_mem((Ptr*)&srvPar->reason.val, srvPar->reason.len);
+	if (NULL == srvPar->reason.val)
+	{
+		switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR, "failed, memory alloc\n");
+		return SWITCH_STATUS_FALSE;
+	}
+
+	strncpy((char*)srvPar->reason.val,
+			(const char *)reason,
+			srvPar->reason.len);
+
+	srvPar->reason.val[srvPar->reason.len] = '\0';
+
+	mg_get_time_stamp(&srvPar->time);
+
+	printf("reason[%s], len[%d]\n",srvPar->reason.val, srvPar->reason.len);
+
+
+	return SWITCH_STATUS_SUCCESS;
+} 
+/*****************************************************************************************************************************/
+
+void mg_get_time_stamp(MgMgcoTimeStamp *timeStamp)
+{
+	DateTime dt;           
+	Txt      dmBuf[16];   
+	U32 	    usec;
+
+	usec = 0;
+
+	/*-- Get system date and time via Trillium stack API --*/
+	SGetRefDateTimeAdj(0, 0, &dt, &usec);
+
+	/*-- Now fill the time and date in the target --*/
+	MG_ZERO(&dmBuf[0], 16);
+
+	sprintf(dmBuf, "%04d%02d%02d",
+			(S16)(dt.year) + 1900, (S16)(dt.month), (S16)(dt.day));
+	cmMemcpy((U8*) &timeStamp->date.val[0], (U8*) &dmBuf[0], 8);
+
+	MG_ZERO(&dmBuf[0], 16);
+	sprintf(dmBuf, "%02d%02d%02d%02d",
+			(S16)(dt.hour), (S16)(dt.min), (S16)(dt.sec), (S16)(usec/10000));
+	cmMemcpy((U8*) &timeStamp->time.val[0], (U8*) &dmBuf[0], 8);
+
+	/*-- Setup the other stuff --*/
+	timeStamp->pres.pres = PRSNT_NODEF;
+	timeStamp->date.pres = PRSNT_NODEF;
+	timeStamp->date.len  = 8;
+	timeStamp->time.pres = PRSNT_NODEF;
+	timeStamp->time.len  = 8;
+
+	switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,"mg_get_time_stamp: time(%s)\n", dmBuf);
+}
+/*****************************************************************************************************************************/
+switch_status_t  mg_create_mgco_command(MgMgcoCommand  *cmd, uint8_t apiType, uint8_t cmdType)
+{
+	MgMgcoCommandReq     *cmdReq;
+	MgMgcoCmdReply       *cmdRep;
+	switch_status_t        ret;
+
+	cmdReq = NULL;
+	cmdRep = NULL;
+
+	cmMemset((U8 *)cmd, 0, sizeof(MgMgcoCommand));
+
+	MG_SET_VAL_PRES(cmd->cmdType, apiType);
+
+	/* Allocate the event structure */
+	switch(apiType)
+	{
+		/* For command Request */
+		case CH_CMD_TYPE_REQ:
+			{
+				if(SWITCH_STATUS_FALSE == (ret = mg_stack_alloc_mem((Ptr*)&cmd->u.mgCmdReq[0],sizeof(MgMgcoCommandReq)))){
+					return ret;
+				}
+
+				if (NULL == cmd->u.mgCmdReq[0]) {
+					switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"mg_create_mgco_command: failed, memory alloc\n");
+					return SWITCH_STATUS_FALSE;
+				}
+
+				cmdReq = cmd->u.mgCmdReq[0];
+				cmdReq->pres.pres = PRSNT_NODEF;
+				cmdReq->cmd.type.pres = PRSNT_NODEF;
+				cmdReq->cmd.type.val = cmdType;
+				switch (cmdType)
+				{
+					case MGT_SVCCHG:
+						cmdReq->cmd.u.svc.pres.pres = PRSNT_NODEF;
+						break;
+
+					case MGT_NTFY:
+						cmdReq->cmd.u.ntfy.pres.pres = PRSNT_NODEF;
+						break;
+				} /* switch cmdType  */
+				break;         
+			}
+
+			/* For command Response */
+		case CH_CMD_TYPE_RSP:
+			{
+				if(SWITCH_STATUS_FALSE == (ret = mg_stack_alloc_mem((Ptr*)&cmd->u.mgCmdRsp[0],sizeof(MgMgcoCmdReply)))){
+					return ret;
+				}
+
+				if (NULL == cmd->u.mgCmdRsp[0]) {
+					switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"mg_create_mgco_command: failed, memory alloc\n");
+					return SWITCH_STATUS_FALSE;
+				}
+				cmdRep = cmd->u.mgCmdRsp[0]; 
+				cmdRep->pres.pres = PRSNT_NODEF;
+				cmdRep->type.pres = PRSNT_NODEF;
+				cmdRep->type.val = cmdType;
+				switch (cmdType)
+				{
+					case MGT_ADD:
+						cmdRep->u.add.pres.pres = PRSNT_NODEF;
+						break; 
+
+					case MGT_MOVE:
+						cmdRep->u.move.pres.pres = PRSNT_NODEF;
+						break; 
+
+					case MGT_MODIFY:
+						cmdRep->u.mod.pres.pres = PRSNT_NODEF;
+						break; 
+
+					case MGT_SUB:  
+						cmdRep->u.sub.pres.pres = PRSNT_NODEF;
+						break; 
+
+					case MGT_SVCCHG:  
+						cmdRep->u.svc.pres.pres =  PRSNT_NODEF;
+						break; 
+
+					case MGT_AUDITVAL:  
+						cmdRep->u.aval.type.pres =  PRSNT_NODEF;
+						break; 
+					case MGT_AUDITCAP:  
+						cmdRep->u.acap.type.pres =  PRSNT_NODEF;
+						break; 
+
+				} /* switch cmdType  */
+				break;         
+			}
+
+		default:
+			switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR,"mg_create_mgco_command: failed, invalid Cmd type[%d]\n",apiType); 
+			return SWITCH_STATUS_FALSE;
+	} /* switch -apiType */
+
+	return SWITCH_STATUS_SUCCESS;
+}
+/*****************************************************************************************************************************/
+
+void mg_fill_null_context(MgMgcoContextId* ctxt)
+{
+	MG_SET_TKN_VAL_PRES(&ctxt->type, MGT_CXTID_NULL, PRSNT_NODEF);
+}	
+/*****************************************************************************************************************************/