Resource Layer

리소스 계층은 유사한 목적을 위한 object 집합이며 또 그 사용법에 대한 프로토콜을 말한다. 호스트는 opencable 에서 규정한 기본적인 function set(resource) 을 반드시 가지고 있어야 하며 POD는 host 가 보유한 resource 의 종류를 미리 알고 필요에 따라 그사용을 요청한다. 각 resource 는 resource id 로 구분된다.
session layer 로 부터 받은 data 는 byte 단위의 array 이다. 이 array byte 데이터를 규격에서 제시한 resource object 의 데이터 구조로 바꿔서 application layer 로 보내는 역할이다.
이제 직접 소스를 보자.

/* =========================================================================
    Required Function Decription
========================================================================= */
void resourceTask()
{
	CABLE_Q	 *pPodMsg, podMsg;
 
	while(1)
	{
		pPodMsg = message_receive_timeout (pResourceQid, TIMEOUT_INFINITY);
		podMsg = *pPodMsg;
		message_release (pResourceQid, pPodMsg);
 
			switch(podMsg.tag)
			{
				case CI_SESSION_TAG:         // 세션 계층으로 부터 올라올 때
					#ifdef LAYER_DEBUG_CHECK
						ARENA_Print(("\n[DEBUG-PODLayer-ResourceLayer-resourceTask]Rcv Session Msg In Session \n"));
					#endif
					parse_APDU(&podMsg);
	   				free(podMsg.ptr);
	   			break;
 
	   			case CI_APPLICATION_TAG:            // 애플리 케이션 계층에서 내려올 때
					#ifdef LAYER_DEBUG_CHECK
						ARENA_Print(("\n[DEBUG-PODLayer-ResourceLayer-resourceTask]Rcv App Msg In Session Size %d\n",sizeof(podMsg.ptr)));
					#endif
		   			make_APDU(&podMsg);
		   		break;
 
		   		case CI_LAYER_CLOSE_TAG:              // 종료 할 때
				//	printf("\n[POD_CI] RESOURCE TASK SUSPEND\n");
					message_delete_queue (pResourceQid);
					task_exit (0);
				break;
 
 
				default:		
				#ifdef ERR_CHECK		
				{
					ARENA_Print(("[ERR-PODLayer-ResourceLayer-Task] Illegal Message Tag(RESOURCE) = %d\n",podMsg.tag));
				}
				#endif
				break;
			}
	}
}

다른 계층과 마찬가지로 독립된 하나의 태스크로 이루어져 있다. 또한 case 로 각각의 상황에 맞게 정해진 루틴을 수행하도록 했다.
우선 APDU 를 파싱하는 부분부터 보기로 하자.
리소스 부분은 다른 계층과는 비교도 안될 정도로 tag 가 많다. 그 만큼 기능이 많다고 생각하면 되겠다.
아무래도 하위에서 상위 부분으로 올라가면 올라갈수록 복잡해지는 건 당연한 일이다. 각각의 상황에 맞게 처리를 수행한 후에 알맞는 상단의 애플리케이션 계층으로 보낸다. 좀더 자세히 설명하자면, 상단의 애플리케이션에서의 태스크가 또하나 만들어 지면서 돌아가게 된다.

/* =========================================================================
    Required Function Decription
========================================================================= */
message_queue_t *select_app(U16 ssnb)
 
{
//	message_queue_t	pTargetQid=0;		//edit ty
	message_queue_t	*qid;// = 0;		//by ty
 
	switch(ssnb_rid[ssnb-1])
	{
		case POD_RESOURCE_MANAGER:
			qid = pRmQid;	
		break;
 
		case POD_APPLICATION_INFO:
			qid = pInfoQid;
		break;
 
		case POD_CONDITIONAL_ACCESS_SUPPORT:
			qid = pCaQid;
		break;
 
		case POD_HOST_CONTROL:
			qid = pHcQid;
		break;
 
		case POD_SYSTEM_TIME:
			qid = pTimeQid;
		break;
 
		case POD_EXTENDED_CHANNEL_SUPPORT:
			qid = pEcQid;
		break;
 
		case POD_MMI:
			qid = pMmiQid;
		break;
/*		
		case POD_LOW_SPEED_COMMUNICATION:
			qid =pLscQid;
		break;
 
		case POD_GENERIC_IPPV_SUPPORT:
			qid = pIppvQid;
		break;
*/
		case POD_COPY_PROTECTION:
			qid = pCpQid;
		break;
 
		case POD_HOMING:
			qid = pHomingQid;
		break;
 
		case POD_GENERIC_FEATURE_CONTROL:
			qid = pGfQid;
		break;
 
		case POD_SPECIFIC_APPLICATION_SUPPORT:
			qid = pSasQid;
		break;
 
		case POD_GENERIC_DIAGNOSTIC:
			qid = pGenericDiagnosticQid;
		break;
 
		case POD_SYSTEM_CONTROL:
			qid = pScQid;
		break;
 
		default:
		#ifdef ERR_CHECK
		{
			ARENA_Print(("[ERROR-PODLayer-SessionLayer-select_app] Illegal session number pattern => [qid=%x] [ssnb=%x]\n",ssnb_rid[ssnb-1],ssnb));
		}
		#endif
		break;
	}
	return(qid);
}

이번에는 APDU 를 만드는 루틴을 보도록 하자!

void make_APDU(struct MESSAGE_Q* msgbuf)
{
	struct	PROFILE_OBJ 					*profile;
 
	struct	APP_INFO_REQ_OBJ				*app_info_req;
	struct	SERVER_QUERY_OBJ				*server_query;
 
	struct	CA_PMT_INQ_OBJ					*capmt;
	struct	OOB_RXTX_TUNE_CNF_OBJ			*oobtx;
	struct	OOB_RXTX_TUNE_CNF_OBJ			*oobrx;
	struct	SYSTEM_TIME_CNF_OBJ				*stime;
	struct	INBAND_TUNE_CNF_OBJ				*inbandtune;
 
	struct	OPEN_MMI_CNF_OBJ				*ommicnf;
	struct	CLOSE_MMI_CNF_OBJ				*cmmicnf;
 
	struct	COMMS_REPLY_OBJ				*comreply;
	struct	COMESSAGE_OBJ					*comessage;
	struct	PROGRAM_REQ_OBJ				*program;
	struct	PURCHASE_REQ_OBJ				*purchase;
	struct	CANCEL_REQ_OBJ					*cancel;
	struct	HISTORY_REQ_OBJ					*history;
	struct	NEW_FLOW_REQ_OBJ				*new_flow;
	struct	DELETE_FLOW_REQ_OBJ			*delete_flow;
	struct	LOST_FLOW_CNF_OBJ				*lost_flow;
 
	struct	NEW_FLOW_CNF_OBJ				*new_flow_cnf;
	struct	DELETE_FLOW_CNF_OBJ			*delete_flow_cnf;
	struct	LOST_FLOW_IND_OBJ				*lost_flow_ind;
	struct	SET_DSG_MODE_OBJ				*set_dsg_mode;
	struct	DSG_PACKET_ERROR_OBJ			*dsg_packet_error;
 
	struct	CP_OPEN_CNF_OBJ				*cp_open;
	struct	CP_DATA_CNF_OBJ					*cp_data;
	struct	CP_SYNC_CNF_OBJ				*cp_sync;
	struct	FEATURE_LIST_OBJ				*feature_list;
	struct	FEATURE_PARAMETERS_OBJ			*feature_parameter;
	struct	FEATURE_PARAMETERS_CNF_OBJ	*parameters_cnf;
	struct	DIAGNOSTIC_CNF_OBJ				*diagnostic_cnf;
	struct	HOST_INFO_RESPONSE_OBJ			*host_info_response;
	struct	CODE_VERSION_TABLE_REPLY_OBJ	*code_version_table_reply;
	struct	HOST_DOWNLOAD_CONTROL_OBJ	*host_download_control;
 
	struct	SAS_CONNECT_RQST_OBJ			*sas_connect_rqst;
 
//	struct	SAS_DATA_RQST_OBJ				*sas_data_rqst;
 
	struct	SAS_DATA_AV_OBJ					*sas_data_av;
	struct	SAS_DATA_CNF_OBJ				*sas_data_cnf;
	struct	SAS_SERVER_QUERY_OBJ			*sas_server_query;
	struct	SAS_SERVER_REPLY_OBJ			*sas_server_reply;
 
	U8	tcid;
	U16	ssnb;
	U32 tag;
 
	tcid = msgbuf->tcid;
	ssnb = msgbuf->ssnb;
	tag = msgbuf->pri;
 
	switch(tag)
	{
//RESOURCE_MANAGER========================================================
		case PROFILE_INQ:
			make_NODATA(tag, tcid, ssnb);
		break;
 
		case PROFILE_CHANGE:
			make_NODATA(tag, tcid, ssnb);
		break;
 
		case PROFILE_REPLY:
			profile = (struct PROFILE_OBJ*)msgbuf->ptr;
			make_PROFILE_REPLY(profile, tcid, ssnb);
			free(profile);
		break;

위에서 보면 알겠지만, 많은 struct 가 선언되어 있다. 모두 각각의 object tag 를 위한 것들이다. 결국은 아래의 세션 계층으로 내려 보낸다.

  • computer/digitalarena/resource_layer.txt
  • Last modified: 4 years ago
  • by likewind