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;
*
*
*/
-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;
+ MgMgcoAmmReq *cmd = &inc_cmd->u.mgCmdInd[0]->cmd.u.add;
+ U32 txn_id = inc_cmd->transId.val;
+
+ /********************************************************************/
+ ctxtId = &inc_cmd->contextId;
+ termLst = mg_get_term_id_list(inc_cmd);
+ termId = termLst->terms[0];
+
+ /********************************************************************/
+ /* 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 */
+ }
+
+ /********************************************************************/
+
+
+ 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:
{
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;
}
/*****************************************************************************************************************************/
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);
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);
}
+/*****************************************************************************************************************************/
+
+/* 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)
"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)
}
#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;
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));
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) */
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:
{
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;
}
}
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:
{
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:
{
}
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;
}
/*****************************************************************************************************************************/
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);