Merge branch 'nsg-4.3' of git.sangoma.com:smg_freeswitch into nsg-4.3

This commit is contained in:
Mathieu Rene 2012-07-17 17:12:22 -04:00
commit c6a75aa4ee
6 changed files with 409 additions and 24 deletions

View File

@ -46,6 +46,63 @@ void megaco_peer_profile_release(mg_peer_profile_t *profile)
switch_thread_rwlock_unlock(profile->rwlock);
}
megaco_profile_t* megaco_get_profile_by_suId(SuId suId)
{
megaco_profile_t* profile = NULL;
void *val = NULL;
switch_hash_index_t *hi = NULL;
int found = 0x00;
const void *var;
/*iterate through profile list to get requested suID profile */
for (hi = switch_hash_first(NULL, megaco_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, &var, NULL, &val);
profile = (megaco_profile_t *) val;
if (profile->idx == suId) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Got profile[%s] associated with suId[%d]\n",profile->name, suId);
found = 0x01;
break;
}
}
if(!found){
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " Not able to find profile associated with suId[%d]\n",suId);
return NULL;
}
return profile;
}
mg_context_t *megaco_find_context_by_suid(SuId suId, uint32_t context_id)
{
mg_context_t *result = NULL;
megaco_profile_t* profile = NULL;
if(NULL == (profile = megaco_get_profile_by_suId(suId))){
return NULL;
}
if (context_id > MG_MAX_CONTEXTS) {
return NULL;
}
switch_thread_rwlock_rdlock(profile->contexts_rwlock);
/* Context exists */
if (profile->contexts_bitmap[context_id % 8] & (1 << (context_id / 8))) {
for (result = profile->contexts[context_id % MG_CONTEXT_MODULO]; result; result = result->next) {
if (result->context_id == context_id) {
break;
}
}
}
switch_thread_rwlock_unlock(profile->contexts_rwlock);
return result;
}
mg_context_t *megaco_get_context(megaco_profile_t *profile, uint32_t context_id)
{
mg_context_t *result = NULL;

View File

@ -29,36 +29,204 @@ const char *mg_service_change_reason[] = {
*
*
*/
switch_status_t handle_mg_add_cmd(MgMgcoAmmReq *addReq)
switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *inc_cmd)
{
int descId;
for (descId = 0; descId < addReq->dl.num.val; descId++) {
switch (addReq->dl.descs[descId]->type.val) {
MgMgcoContextId *ctxtId;
int descId;
MgStr errTxt;
MgMgcoInd *mgErr;
MgMgcoTermId *termId;
MgMgcoTermIdLst* termLst;
int err_code;
int i;
int j;
int fmtCnt;
MgMgcoAmmReq *cmd = &inc_cmd->u.mgCmdInd[0]->cmd.u.add;
U32 txn_id = inc_cmd->transId.val;
MgMgcoLocalDesc *local;
MgMgcoRemoteDesc *remote;
MgMgcoLclCtlDesc *locCtl;
CmSdpInfo *sdp;
MgMgcoLocalParm *lclParm;
MgMgcoTermStateDesc *tstate;
CmSdpMedFmtRtpList *fmt_list;
MgMgcoTermStateParm *tsp;
TknU8 *fmt;
CmSdpMedProtoFmts *format;
/********************************************************************/
ctxtId = &inc_cmd->contextId;
termLst = mg_get_term_id_list(inc_cmd);
termId = termLst->terms[0];
/* For Matt - termId->name.lcl.val - to get the termination id name */
/********************************************************************/
/* Validating ADD request *******************************************/
/*-- NULL Context & ALL Context not applicable for ADD request --*/
if ((NOTPRSNT != ctxtId->type.pres) &&
((MGT_CXTID_ALL == ctxtId->type.val) ||
(MGT_CXTID_NULL == ctxtId->type.val))) {
switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR," ADD Request processing failed, Context ALL/NULL not allowed\n");
mg_util_set_ctxt_string(&errTxt, ctxtId);
err_code = MGT_MGCO_RSP_CODE_PROT_ERROR;
goto error;
}
/********************************************************************/
/* Allocate context - if context type is CHOOSE */
if ((NOTPRSNT != ctxtId->type.pres) &&
(MGT_CXTID_CHOOSE == ctxtId->type.val)){
/* TODO - Matt */
}
/********************************************************************/
/* Allocate new RTP termination - If term type is CHOOSE */
if ((NOTPRSNT != termId->type.pres) &&
(MGT_TERMID_CHOOSE == termId->type.val)){
/* TODO - Matt */
/* allocate rtp term and associated the same to context */
/********************************************************************/
}else{ /* Physical termination */
/* TODO - Matt - associate physical termination to context */
}
/********************************************************************/
for (descId = 0; descId < cmd->dl.num.val; descId++) {
switch (cmd->dl.descs[descId]->type.val) {
case MGT_MEDIADESC:
{
int mediaId;
for (mediaId = 0; mediaId < addReq->dl.descs[descId]->u.media.num.val; mediaId++) {
MgMgcoMediaPar *mediaPar = addReq->dl.descs[descId]->u.media.parms[mediaId];
for (mediaId = 0; mediaId < cmd->dl.descs[descId]->u.media.num.val; mediaId++) {
MgMgcoMediaPar *mediaPar = cmd->dl.descs[descId]->u.media.parms[mediaId];
switch (mediaPar->type.val) {
case MGT_MEDIAPAR_LOCAL:
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MGT_MEDIAPAR_LOCAL");
/* Matt - check local descriptor processing */
local = &mediaPar->u.local;
sdp = local->sdp.info[0];
for (i = 0; i < sdp->mediaDescSet.numComp.val; i++) {
/* sdp formats */
for (j = 0; j <
sdp->mediaDescSet.mediaDesc[i]->field.par.numProtFmts.val; j++)
{
format = sdp->mediaDescSet.mediaDesc[i]->field.par.pflst[j];
/* Matt - format has field for T38 also */
if ((format->protType.pres != NOTPRSNT) &&
(format->protType.val == CM_SDP_MEDIA_PROTO_RTP)) {
/* protocol type RTP */
fmt_list = &format->u.rtp;
/* print format */
for(fmtCnt = 0; fmtCnt < fmt_list->num.val; fmtCnt++){
fmt = &fmt_list->fmts[i]->val;
if(fmt->pres == NOTPRSNT) continue;
printf("Format [%d]\n", fmt->val);
}
}
}
}
break;
}
case MGT_MEDIAPAR_REMOTE:
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MGT_MEDIAPAR_REMOTE");
/* Matt - check remote descriptor processing */
remote = &mediaPar->u.remote;
sdp = remote->sdp.info[0];
/* for Matt - same like local descriptor */
break;
}
case MGT_MEDIAPAR_LOCCTL:
{
/* Matt - check Local Control descriptor processing */
locCtl = &mediaPar->u.locCtl;
for (i = 0; i < locCtl->num.val; i++){
lclParm = locCtl->parms[i];
if (PRSNT_NODEF == lclParm->type.pres){
switch(lclParm->type.val)
{
case MGT_LCLCTL_MODE:
{
/* Mode Property */
printf("MGT_LCLCTL_MODE - Mode value [%d]\n", lclParm->u.mode.val);
break;
}
case MGT_LCLCTL_RESVAL:
{
/* Reserve Value */
printf("MGT_LCLCTL_RESVAL: Reserve Value[%d] \n", lclParm->u.resVal.val);
break;
}
case MGT_LCLCTL_RESGRP:
{
/* Reserve group */
printf("MGT_LCLCTL_RESGRP: Reserve Group[%d]\n", lclParm->u.resGrp.val);
break;
}
case MGT_LCLCTL_PROPPARM:
{
/* Properties (of a termination) */
/* Matt - See how we can apply this to a termination */
printf("MGT_LCLCTL_PROPPARM: \n");
break;
}
default:
printf("Invalid local control descriptor type[%d]\n",lclParm->type.val);
break;
}
}
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MGT_MEDIAPAR_LOCCTL");
break;
}
case MGT_MEDIAPAR_TERMST:
{
/* Matt - apply termination state descriptor */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "MGT_MEDIAPAR_TERMST");
tstate = &mediaPar->u.tstate;
for (i = 0; i < tstate->numComp.val; i++)
{
/* Matt to see how to apply below descriptors to a termination */
tsp = tstate->trmStPar[i];
if (PRSNT_NODEF == tsp->type.pres) {
switch(tsp->type.val)
{
case MGT_TERMST_PROPLST:
{
/* Matt to see how to apply properties to a termination */
/* Properties of a termination */
printf("MGT_TERMST_PROPLST:\n");
break;
}
case MGT_TERMST_EVTBUFCTL:
{
/* Event /buffer Control Properties */
printf(" MGT_TERMST_EVTBUFCTL: value[%d]\n", tsp->u.evtBufCtl.val);
break;
}
case MGT_TERMST_SVCST:
{
/* Service State Properties */
printf(" MGT_TERMST_SVCST: value[%d]\n", tsp->u.svcState.val);
break;
}
default:
printf("Invalid termination state descriptor type[%d]\n",tsp->type.val);
break;
}
}
}
break;
}
case MGT_MEDIAPAR_STRPAR:
@ -92,8 +260,23 @@ switch_status_t handle_mg_add_cmd(MgMgcoAmmReq *addReq)
}
}
/* Matt - to provide the response SDP structure which needs to fill in ADD command response */
/* Matt - to indicate if there is any failure while processing add message */
/* Kapil - to return error if there is any failure based on Matt's indication */
/* Kapil - to fill the response structure and call the response API to send ADD response */
return SWITCH_STATUS_SUCCESS;
error:
if (SWITCH_STATUS_SUCCESS ==
mg_build_mgco_err_request(&mgErr, txn_id, ctxtId, err_code, &errTxt)) {
sng_mgco_send_err(mg_profile->idx, mgErr);
}
mg_free_cmd(cmd);
return SWITCH_STATUS_FALSE;
}
/*****************************************************************************************************************************/

View File

@ -133,7 +133,7 @@ int sng_mgco_mg_get_status(int elemId, MgMngmt* cfm, megaco_profile_t* mg_cfg, m
switch_status_t mg_send_end_of_axn(SuId suId, MgMgcoTransId* transId, MgMgcoContextId* ctxtId, TknU32* peerId);
void mgco_print_sdp(CmSdpInfoSet *sdp);
void mg_util_set_ctxt_string ( MgStr *errTxt, MgMgcoContextId *ctxtId);
switch_status_t handle_mg_add_cmd(MgMgcoAmmReq *addReq);
switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *addReq);
switch_status_t mg_stack_free_mem(void* msg);
switch_status_t mg_stack_alloc_mem( Ptr* _memPtr, Size _memSize );
MgMgcoMediaDesc* get_default_media_desc(void);
@ -144,6 +144,8 @@ 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);
switch_status_t handle_mg_audit_cmd(SuId suId, MgMgcoCommand *auditReq);
switch_status_t mg_stack_termination_is_in_service(char* term_str, int len);
void mg_util_set_cmd_name_string (MgStr *errTxt, MgMgcoCommand *cmd);
switch_status_t mg_send_modify_rsp(SuId suId, MgMgcoCommand *req);
switch_status_t mg_send_subtract_rsp(SuId suId, MgMgcoCommand *req);

View File

@ -78,6 +78,14 @@ switch_status_t mg_stack_free_mem(void* msg)
}
/*****************************************************************************************************************************/
/* TODO - Matt - to see if term is in service or not */
switch_status_t mg_stack_termination_is_in_service(char* term_str,int len)
{
return SWITCH_STATUS_SUCCESS;
}
/*****************************************************************************************************************************/
S16 mg_fill_mgco_termid ( MgMgcoTermId *termId, char* term_str, int term_len, CmMemListCp *memCp)
@ -351,6 +359,55 @@ void mg_util_set_ctxt_string ( MgStr *errTxt, MgMgcoContextId *ctxtId)
"info, error-text is: %s\n", __PRETTY_FUNCTION__,errTxt->val);
}
/*****************************************************************************************************************************/
void mg_util_set_cmd_name_string (MgStr *errTxt, MgMgcoCommand *cmd)
{
MG_ZERO((errTxt->val), sizeof(errTxt->val));
errTxt->len = 0;
if ((!cmd) && (!cmd->u.mgCmdInd[0])) {
switch(cmd->u.mgCmdInd[0]->cmd.type.val)
{
case MGT_AUDITCAP:
errTxt->val[0]='\"';
errTxt->val[1]='A';
errTxt->val[2]='u';
errTxt->val[3]='d';
errTxt->val[4]='i';
errTxt->val[5]='t';
errTxt->val[6]='C';
errTxt->val[7]='a';
errTxt->val[8]='p';
errTxt->val[9]='a';
errTxt->val[10]='b';
errTxt->val[11]='i';
errTxt->val[12]='l';
errTxt->val[13]='i';
errTxt->val[14]='t';
errTxt->val[15]='y';
errTxt->val[16]='\"';
errTxt->len = 17;
break;
case MGT_MOVE:
errTxt->val[0]='\"';
errTxt->val[1]='M';
errTxt->val[2]='o';
errTxt->val[3]='v';
errTxt->val[4]='e';
errTxt->val[5]='\"';
errTxt->len = 6;
break;
default:
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s: Not expected command Type[%d]\n",
__PRETTY_FUNCTION__,cmd->u.mgCmdInd[0]->cmd.type.val);
break;
}
}
}
/*****************************************************************************************************************************/
void mgco_print_sdp(CmSdpInfoSet *sdp)

View File

@ -233,6 +233,9 @@ static switch_status_t mgco_parse_local_sdp(mg_termination_t *term, CmSdpInfoSet
}
#endif
/* KAPIL- NOTE : We are using Command mode operation of MEGACO stack, so we will always get command indication instead of transaction */
/* Below API is not useful ... just leaving as it is...*/
void handle_mgco_txn_ind(Pst *pst, SuId suId, MgMgcoMsg* msg)
{
size_t txnIter;
@ -425,8 +428,12 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd)
MgMgcoInd *mgErr;
MgStr errTxt;
MgMgcoContextId ctxtId;
MgMgcoContextId *inc_context;
MgMgcoTermIdLst* termLst;
MgMgcoTermId *termId;
int count;
int err_code;
megaco_profile_t* mg_profile;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s: Received Command Type[%s] \n", __PRETTY_FUNCTION__, PRNT_MG_CMD_TYPE(cmd->cmdType.val));
@ -442,15 +449,8 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd)
ctxtId.val.pres = NOTPRSNT;
mg_util_set_txn_string(&errTxt, &txn_id);
if (SWITCH_STATUS_SUCCESS == mg_build_mgco_err_request(&mgErr, txn_id, &ctxtId,
MGT_MGCO_RSP_CODE_INVLD_IDENTIFIER, &errTxt)) {
sng_mgco_send_err(suId, mgErr);
}
/* deallocate the msg */
mg_free_cmd(cmd);
return ;
err_code = MGT_MGCO_RSP_CODE_INVLD_IDENTIFIER;
goto error;
}
/* Get the termination Id list from the command(Note: GCP_2_1 has termination list , else it will be termination Id) */
@ -458,12 +458,80 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd)
if ((NULL == termLst) || (NOTPRSNT == termLst->num.pres)) {
/* termination-id not present , error */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Termination-Id Not received..rejecting command \n");
mg_free_cmd(cmd);
return ;
/*-- Send Error to MG Stack --*/
MG_ZERO(&ctxtId, sizeof(MgMgcoContextId));
ctxtId.type.pres = NOTPRSNT;
ctxtId.val.pres = NOTPRSNT;
mg_util_set_txn_string(&errTxt, &txn_id);
err_code = MGT_MGCO_RSP_CODE_INVLD_IDENTIFIER;
goto error;
}
termId = termLst->terms[0];
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Termination-Id received..value[%s] type[%d] \n", termId->name.lcl.val, termId->type.val);
/* Not sure - IF Stack fills term type properly..but adding code just to be sure ...*/
if ((PRSNT_NODEF == termId->type.pres) &&
(MGT_TERMID_OTHER == termId->type.val)) {
/* Checking the $ in the pathname */
if ((PRSNT_NODEF == termId->name.pres.pres) &&
(PRSNT_NODEF == termId->name.lcl.pres)) {
for (count = 0; count < termId->name.lcl.len; count++) {
if (termId->name.lcl.val[count] == '$') {
termId->type.val = MGT_TERMID_CHOOSE;
break;
}
if (termId->name.lcl.val[count] == '*') {
termId->type.val = MGT_TERMID_ALL;
break;
}
}
}
}
/*If term type is other then check if that term is configured with us..for term type CHOOSE/ALL , no need to check */
if (MGT_TERMID_OTHER == termId->type.val){
if(SWITCH_STATUS_FALSE != mg_stack_termination_is_in_service((char*)termId->name.lcl.val, termId->name.lcl.len)){
mg_util_set_term_string(&errTxt, termId);
err_code = MGT_MGCO_RSP_CODE_UNKNOWN_TERM_ID;
goto error;
}
}
/* Validate Context - if context is specified then check if its present with us */
inc_context = &cmd->contextId;
MG_ZERO(&ctxtId, sizeof(MgMgcoContextId));
memcpy(&ctxtId, inc_context, sizeof(MgMgcoContextId));
if(NOTPRSNT == inc_context->type.pres){
goto ctxt_error;
}else if(MGT_CXTID_OTHER == inc_context->type.pres){
if(NOTPRSNT != inc_context->val.pres){
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"Context specific request for contextId[%d]\n",inc_context->val.val);
/* check if context present with us */
if(NULL == megaco_find_context_by_suid(suId, inc_context->val.val)){
goto ctxt_error;
}
}else{
/* context id value not present - in case of type OTHER we should have context value */
goto ctxt_error;
}
}
/*mgAccEvntPrntMgMgcoCommand(cmd, stdout);*/
/*get mg profile associated with SuId */
if(NULL == (mg_profile = megaco_get_profile_by_suId(suId))){
goto error1;
}
switch(cmd->cmdType.val)
{
case CH_CMD_TYPE_IND:
@ -475,7 +543,7 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd)
{
case MGT_ADD:
{
handle_mg_add_cmd(&cmd->u.mgCmdInd[0]->cmd.u.add);
handle_mg_add_cmd(mg_profile, cmd);
mg_send_add_rsp(suId, cmd);
break;
}
@ -488,9 +556,10 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd)
}
case MGT_MOVE:
{
/*MgMgcoAmmReq *addReq = &cmdReq->cmd.u.move;*/
break;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MOVE Method Not Yet Supported\n");
err_code = MGT_MGCO_RSP_CODE_UNSUPPORTED_CMD;
mg_util_set_cmd_name_string(&errTxt, cmd);
goto error;
}
case MGT_SUB:
{
@ -511,7 +580,9 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd)
case MGT_AUDITCAP:
{
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Audit-Capability Method Not Yet Supported\n");
break;
err_code = MGT_MGCO_RSP_CODE_UNSUPPORTED_CMD;
mg_util_set_cmd_name_string(&errTxt, cmd);
goto error;
}
case MGT_AUDITVAL:
{
@ -542,6 +613,18 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd)
}
return;
ctxt_error:
err_code = MGT_MGCO_RSP_CODE_UNKNOWN_CTXT;
error:
if (SWITCH_STATUS_SUCCESS ==
mg_build_mgco_err_request(&mgErr, txn_id, &ctxtId, err_code, &errTxt)) {
sng_mgco_send_err(suId, mgErr);
}
error1:
mg_free_cmd(cmd);
return;
}
/*****************************************************************************************************************************/

View File

@ -139,6 +139,9 @@ mg_context_t *megaco_get_context(megaco_profile_t *profile, uint32_t context_id)
mg_context_t *megaco_choose_context(megaco_profile_t *profile);
void megaco_release_context(mg_context_t *ctx);
megaco_profile_t* megaco_get_profile_by_suId(SuId suId);
mg_context_t *megaco_find_context_by_suid(SuId suId, uint32_t context_id);
switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload);
switch_status_t sng_mgco_start(megaco_profile_t* profile);
switch_status_t sng_mgco_stop(megaco_profile_t* profile);