Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: High level CA implementation..



On Tue November 2 2004 1:25 pm, Andrew de Quincey wrote:
> On Tuesday 02 Nov 2004 06:24, Manu Abraham wrote:
> > On Mon November 1 2004 10:44 pm, Holger Waechtler wrote:
> > > Manu Abraham wrote:
> > > >Hi,
> > > > Can somebody explain me a little bit how a high level CA
> > > > driver/system be implemented as per the V3 API ?
> > > >
> > > >The current implementation is based on the Transport Level driver,
> > > > whereas i'm looking at a higher level CA system, where most of the
> > > > transport level functions are held in the ASIC, as in the case of the
> > > > Twinhan card.
> > > >
> > > >If somebody could give me an idea, that would be really helpful.
> > >
> > > By setting slot->type to CA_CI_LINK you can implement your driver on
> > > the link layer interface if you want to do so. Take a look on Andrew's
> > > dvb_ca_en50221.c implementation used by the budget_ci driver, is your
> > > interface really on a higher level than the link layer?
> >
> > Yes, it is almost as good as the interface is exposed directly to
> > userspace. Almost everything is done in the ASIC.
> >
> > Even dvb libraries are implemented in the driver itself by the
> > manufacturer, which can at least taken out into userspace.
> >
> > What i am wondering is that, then an implementation of such a DVB driver
> > would not be adhering to the linux-DVB API ?
> >
> >
> > Andrew's driver works in the transport layer and there is no use for such
> > an implementation in this case. All the layers happen to be embedded into
> > the ASIC. The only thing one can do is send a message to the
> > CA_SEND_MESSAGE, or get a message CA_GET_MESSAGE or get the application
> > info CA_GET_APP_INFO. Nothing more
>
		I have the manufacturer's code with me, should i get you a copy ? I had once 
sent it to the mailing list some time back.




> IMO, those three should be exposed. What kind of messages can you
> send/receive to it? Can you give an example?
>


These are the functions that do get called. Would you like to take a deeper 
look ? I have the source with me.

static int CI_Get_CamState(bktr_ptr_t bktr, P_CAM_STATE pCAM_State);
static int CI_Get_AppInfo(bktr_ptr_t bktr, P_APP_INFO pApp_Info);
static int CI_Set_CA_PMT(bktr_ptr_t bktr, P_CA_PMT pCa_Pmt);


-------------------------------------------------------------------------------
int CI_Get_CamState(bktr_ptr_t bktr, P_CAM_STATE pCAM_State)
{
    PROTOCOL comm = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
    PROTOCOL result = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb};
    unsigned int Temp;
    
    if (dstPutCommand(bktr, &comm) != 0)
        return -1;
        
    dstCommandReply(bktr, &result);      
    
    Temp = result[4];
	if (Temp == 0xff) {
		pCAM_State->CAM_exist_flag = NON_CI_INFO;
		pCAM_State->MMI_info_flag = NON_CI_INFO;
		return 0;
	}

	if (Temp & 0x80)
		pCAM_State->CAM_exist_flag = ME0;
	else if (Temp & 0x40)
		pCAM_State->CAM_exist_flag = ME1;
	else
		pCAM_State->CAM_exist_flag = NON_CI_INFO;

	if (Temp & 0x20)
		pCAM_State->MMI_info_flag = MMI0;
	else if (Temp & 0x10)
		pCAM_State->MMI_info_flag = MMI1;
	else if (Temp & 0x08)
		pCAM_State->MMI_info_flag = MMI0_ClOSE;
	else if (Temp & 0x04)
		pCAM_State->MMI_info_flag = MMI1_CLOSE;
	else
		pCAM_State->MMI_info_flag = NON_CI_INFO;         
	
    //ERRMSG("CAM State: CAM_Exist_Flag=%d, MMI_Info_Flag=%d \n", 
pCAM_State->CAM_exist_flag, pCAM_State->MMI_info_flag);
	    
    return 0;
}
--------------------------------------------------------------------------------------

int CI_Get_AppInfo(bktr_ptr_t bktr, P_APP_INFO pApp_Info)
{
    STRING comm = {0x07, 0x40, 0x00, 0x00, PCMSG_APPLICATION_INFO, 0x00, 0x00, 
0xb8};
    
    if (put8820CiMSG(bktr, comm) != 0) {
        ERRMSG("CI_Get_AppInfo => put8820CiMSG error!!\n");                
        return -1;
    }
    
    pApp_Info->app_type = ca_input[7];
	pApp_Info->application_manufacture = (ca_input[8] << 8) | ca_input[9];
	pApp_Info->manufacture_code = (ca_input[10] << 8) | ca_input[11];
	strcpy(pApp_Info->application_info,(char *)(&(ca_input[12])));
	//ERRMSG("CAM APP_Info: app_type=%d, application_manufacture=%d, 
manufacture_code=%d, application_info=%s \n", 
	         //pApp_Info->app_type, pApp_Info->application_manufacture, 
pApp_Info->manufacture_code, pApp_Info->application_info);
    
    return 0;
}
-----------------------------------------------------------------------------------
int CI_Set_CA_PMT(bktr_ptr_t bktr, P_CA_PMT pCa_Pmt)
{
    unsigned char *pBuffer = pCa_Pmt->CA_PMT_Buf;
    int nSize = pCa_Pmt->nCA_PMT_Size;
    int i = 0;
    
    if (nSize) {
//ERRMSG("CI_Set_CA_PMT %d, 0x%02x, 0x%02x, 0x%02x\n", nSize, pBuffer[0], 
pBuffer[1], pBuffer[nSize-1]);
        for (i = (nSize - 1); i >= 0; i--) {
			pBuffer[i+7] = pBuffer[i];
		}
		nSize += 8;		
		pBuffer[0] = nSize - 1;
		pBuffer[1] = 0x40;
		pBuffer[2] = 0x03;
		pBuffer[3] = 0;
		pBuffer[4] = 0x03;
		pBuffer[5] = nSize - 8;
		pBuffer[6] = 0;		
		for (i = 0; i < (nSize - 1); i++) {
			pBuffer[nSize - 1] += pBuffer[i];
		}
		pBuffer[nSize - 1] = ~pBuffer[nSize - 1] + 1;
		
		if (put8820CiMSG(bktr, pBuffer) != 0) {
            ERRMSG("CI_Set_CA_PMT => put8820CiMSG error!!\n");                
            return -1;
        }
		return 0;
    }

    return -1;
}
------------------------------------------------------------------------


bktr_ptr_t is nothing but a pointer to the structure which contains registers 
of the bt848.




This is the ca_ioctl block

    switch ( cmd ) {
        case CI_GET_APP_INFO:
            memset((void*)&app_info, 0, sizeof(APP_INFO));
            if (CI_Get_AppInfo(bktr, &app_info)) { 
                return -1;
            }
            if ((ret = put_ioctl_bytes((caddr_t)arg, &app_info, 
sizeof(APP_INFO)))) 
                return ret;
            break; 
                
        case CI_GET_CAM_STATE:
            memset((void*)&cam_state, 0, sizeof(CAM_STATE));
            if (CI_Get_CamState(bktr, &cam_state)) { 
                return -1;
            }
            if ((ret = put_ioctl_bytes((caddr_t)arg, &cam_state, 
sizeof(CAM_STATE)))) 
                return ret;
            break; 
            
        case CI_SET_CA_PMT:
            if ( (ret = get_ioctl_bytes(&ca_pmt, (caddr_t)arg, 
sizeof(CA_PMT)))) 
                return ret;
            if (CI_Set_CA_PMT(bktr, &ca_pmt)) {
                ERRMSG("Parser CI_SET_CA_PMT fail !! \n");
                return -1;
            }
            break;

> I think you're going to have to add an extension to the API - theres no
> support for anything like that right now. It'd be good to add a
> standardised extension though.

Yes i too think that would be the way to go, if it has to be extended.

Regards,
Manu





Home | Main Index | Thread Index