All pastes #35280 Raw Edit

Something

public c v1 · immutable
#35280 ·published 2005-12-30 15:01 UTC
rendered paste body
/*    en50221 encoder An implementation for libdvb    an implementation for the en50221 transport layer    Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com)    Copyright (C) 2005 Julian Scheel (julian at jusst dot de)    This library is free software; you can redistribute it and/or modify    it under the terms of the GNU Lesser General Public License as    published by the Free Software Foundation; either version 2.1 of    the License, or (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU Lesser General Public License for more details.    You should have received a copy of the GNU Lesser General Public    License along with this library; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA*/#include <string.h>#include "en50221_application.h"#include "dvbmisc.h"#define verbose		4/* -------------------------------------------------------------------------   Resource Manager */struct en50221_resource* en50221_lookup_resource(struct en50221_resource_identifier *idf){    if(!idf)        return NULL;    int i;    struct en50221_resource *result = NULL;    for(i=0;i<NB_MAX_RESOURCE;i++)    {        struct en50221_resource_identifier chk = resource_list[i].identifier;        if(chk.resource_id_type == idf->resource_id_type &&           chk.resource_class == idf->resource_class &&           chk.resource_type == idf->resource_type)        {            // we ignore the version-check for now            // should be implemented someday to fullfile the specs            result = &resource_list[i];            break;        }    }    return result;}// register a new resource at the Resource Manageruint8_t en50221_register_resource(struct en50221_resource_identifier *identifier,                                  void (*callback_fct)(uint8_t *data)){    // unused elements in the resource_list have    // resource_id = 0    for(i=0;i<NB_MAX_RESOURCE;i++)    {        struct en50221_resource chk = resource_list[i];        if(chk.resource_id == 0)        {            // take this one            chk.resource_id = i+1;            chk.identifier.resource_id_type = resource_idf.resource_id_type;            chk.identifier.resource_class = resource_idf.resource_class;            chk.identifier.resource_type = resource_idf.resource_type;            chk.identifier.resource_version = resource_idf.resource_version;            return(chk.resource_id);        }    }    return 0;}uint8_t* en50221_encode_resource_identifier(struct en50221_resource_identifier *idf, uint8_t *data){    if(!data)        return NULL;        data[0] = idf.resource_type_id << 6 | ((idf.resource_class >> 8) & 0x3f);    data[1] = idf.resource_class & 0xff;    data[2] = (idf.resource_type >> 2) & 0xff;    data[3] = ((res_type & 0x03) << 6) | (res_var & 0x3f);    return data;}// handle incoming TAG_PROFILE messagevoid rm_int_handle_incoming_profile(uint8_t *data){    // the data-stream starts with the length_field;    uint8_t length_field_len;    if(data[0] & 0x80)        length_field_len = 1;    else        length_field_len = 2;        uint8_t *resources = data+length_field_len;    uint8_t num_resources = (uint8_t) asn_1_decode(data) / 4; // each resource_identifier                                                             // has a length of 4 bytes    uint8_t i;    for(i = 0; i < num_resources; i++)    {        struct en50221_resource_identifier res;        res.resource_type_id = (resources[0] >> 6) & 0x03;        res.resource_class = ((resources[0] & 0x3f) << 8) | resources[1];        res.resource_type = (resources[2] << 2) | (resources[3] >> 6);        res.resource_version = resources[3] & 0x3f;                // register this resource        // it's a null-callback, because we won't need        // to pass data between modules        en50221_register_resource(res, NULL);                // move to the next resource        resources += 4;    }}// parse the APDU, and handle it depending on// the tagvoid en50221_rm_callback(uint8_t *data){    // strip the tag from the APDU carried in data    uint32_t tag = (uint32_t ) ((((data[0] << 8) |                            data[1]) << 8) | data[2]);        // print out the tags name    struct tag_type tag_descr;    get_en50221_tag(&tag_descr, tag);    print(verbose, DEBUG, 1, "Received [0x%04x] %s",                tag_id, tag_descr.tag_descr);        switch(tag)    {        case TAG_PROFILE_ENQUIRY:            break;        case TAG_PROFILE:            rm_int_handle_incoming_profile(data+3);            break;    }}/* ----------------------------------------------------------------------------- */uint32_t get_en50221_tag(struct tag_types *tag_descr,			uint32_t en50221_tag){    uint8_t i;    uint32_t tag_id;    /*	get our tag	*/    tag_id = i = 0;    while (tag_id != en50221_tag) {        tag_id = (uint32_t ) ((((tag_table[i].en50221_tag[0] << 8) |            tag_table[i].en50221_tag[1]) << 8) |            tag_table[i].en50221_tag[2]);        if (tag_id == en50221_tag) {            memcpy(tag_descr->en50221_tag, tag_table[i].en50221_tag, 3);            tag_descr->tag_descr = tag_table[i].tag_descr;        } else {            i++;        }    }}/* *	Write to module/session layer */void apdu_request(uint8_t slot_id, uint32_t en50221_tag){	struct tag_types en50221_tag_descr;	uint32_t tag_id;	get_en50221_tag(&en50221_tag_descr, en50221_tag, tag_id);	print(verbose, DEBUG, 1, "Request [0x%04x] %s",		tag_id, en50221_tag_descr.tag_descr);	switch (tag_id) {	/*	length = 0		*/	case TAG_PROFILE_ENQUIRY:	case TAG_PROFILE_CHANGED:	case TAG_APP_INFO_ENQUIRY:	case TAG_ENTER_MENU:	case TAG_CA_INFO_ENQUIRY:	case TAG_ASK_RELEASE:	/*	length = 5 or 7		*/	case TAG_DATE_TIME_ENQUIRY:	}	/*	do an ASN.1 decode	*/	asn_1_encode(length, message);	/*	Req. to session layer	*/	en50221_sl_send_data(slot_id, message);}/* *	This is a callback from the session layer *	(Read from module/session layer) */void apdu_get(int fd, uint32_t en50221_tag){	struct tag_types en50221_tag_descr;	uint32_t tag_id;	tag_id = get_en50221_tag(&en50221_tag_descr, en50221_tag, tag_id);	print(verbose, DEBUG, 1, "Received [0x%04x] %s",		tag_id, en50221_tag_descr.tag_descr);	/*	do an ASN.1 encode	*/	asn_1_decode(message);	/*	Read from session layer	*/}