oscam-2.26.01-11942-802-wit.../reader-nagra-common.c
2026-02-17 09:41:05 +00:00

527 lines
12 KiB
C
Executable File

#include "globals.h"
#include "reader-common.h"
#include "reader-nagra-common.h"
int32_t get_prov_idx(struct s_reader *rdr, const uint8_t *provid)
{
int prov;
for(prov = 0; prov < rdr->nprov; prov++) // search for provider index
{
if(!memcmp(provid, &rdr->prid[prov][2], 2))
{
return (prov);
}
}
return (-1);
}
int32_t nagra_get_emm_type(EMM_PACKET *ep, struct s_reader *rdr)
{
#ifdef READER_NAGRA_MERLIN
if(rdr->cak7type == 3)
{
int i;
switch(ep->emm[0])
{
case 0x83:
ep->type = GLOBAL;
if(rdr->emm83 == 1 && ep->emm[3] == 0x00 && ep->emm[4] == 0x00)
{
return 1;
}
return 0;
case 0x84:
ep->type = SHARED;
for(i = 0; i < rdr->nemm84s; i++)
{
if(!memcmp(rdr->emm84s[i] + 1, ep->emm + 3, 0x05))
{
return 1;
}
}
return 0;
case 0x82:
if(ep->emm[3] == 0x00 && ep->emm[4] == 0x00)
{
ep->type = UNIQUE;
for(i = 0; i < rdr->nemm82u; i++)
{
if(!memcmp(rdr->emm82u[i] + 3, ep->emm + 5, 0x04))
{
return 1;
}
}
}
return 0;
case 0x90:
ep->type = UNIQUE;
if(rdr->cwpkcaid_length && rdr->nuid_length)
{
memset(ep->hexserial, 0x00, 0x08);
ep->hexserial[0] = ep->emm[5];
ep->hexserial[1] = ep->emm[4];
ep->hexserial[2] = ep->emm[3];
ep->hexserial[3] = ep->emm[6];
return (!memcmp(rdr->nuid, ep->hexserial, 4));
}
return 0;
default:
ep->type = UNKNOWN;
return 0;
}
}
else if(rdr->cak7type == 1)
{
int i;
switch(ep->emm[0])
{
case 0x82:
ep->type = GLOBAL;
if(rdr->emm82 == 1 && ep->emm[3] == 0x00 && ep->emm[4] == 0x00 && ep->emm[5] == 0x00)
{
return 1;
}
return 0;
case 0x83:
if(ep->emm[7] == 0x10)
{
ep->type = SHARED;
for(i = 0; i < rdr->nemm83s; i++)
{
if(!memcmp(rdr->emm83s[i] + 1, ep->emm + 3, 0x03))
{
return 1;
}
}
}
else
{
ep->type = UNIQUE;
for(i = 0; i < rdr->nemm83u; i++)
{
if(!memcmp(rdr->emm83u[i] + 1, ep->emm + 3, 0x04))
{
return 1;
}
}
}
return 0;
case 0x84:
ep->type = GLOBAL;
for(i = 0; i < rdr->nemm84; i++)
{
if(!memcmp(rdr->emm84[i] + 1, ep->emm + 3, 0x02))
{
return 1;
}
}
return 0;
case 0x87:
ep->type = SHARED;
for(i = 0; i < rdr->nemm87; i++)
{
if(!memcmp(rdr->emm87[i] + 1, ep->emm + 3, 0x04))
{
return 1;
}
}
return 0;
case 0x90:
ep->type = UNIQUE;
if(rdr->cwpkcaid_length && rdr->nuid_length)
{
memset(ep->hexserial, 0x00, 0x08);
ep->hexserial[0] = ep->emm[5];
ep->hexserial[1] = ep->emm[4];
ep->hexserial[2] = ep->emm[3];
ep->hexserial[3] = ep->emm[6];
return (!memcmp(rdr->nuid, ep->hexserial, 4));
}
return 0;
default:
ep->type = UNKNOWN;
return 0;
}
}
else
#endif
{
int i;
switch(ep->emm[0])
{
case 0x82:
memset(ep->hexserial, 0x00, 0x08);
ep->hexserial[0] = ep->emm[5];
ep->hexserial[1] = ep->emm[6];
ep->hexserial[2] = ep->emm[7];
ep->hexserial[3] = ep->emm[8];
if (!memcmp(rdr->hexserial + 2, ep->hexserial, 0x04))
{
ep->type = UNIQUE;
return 1;
}
else if ((ep->emm[3] == 0x00) && (ep->emm[4] == 0x00) && (ep->emm[5] == 0x00) && (ep->emm[6] == 0x00) && (ep->emm[7] == 0x00) && ((ep->emm[8] == 0x04) || (ep->emm[8] == 0xD3)) && ((ep->emm[9] == 0x84) || (ep->emm[9] == 0x8F) || (ep->emm[9] == 0x87)))
{
ep->type = GLOBAL;
return 1;
}
return 0;
case 0x84:
memset(ep->hexserial, 0x00, 0x08);
memcpy(ep->hexserial, ep->emm + 5, 3);
i = get_prov_idx(rdr, ep->emm + 3);
if((ep->emm[3] == 0x00 || ep->emm[3] == 0x01) && (ep->emm[5] == 0x00) && (ep->emm[6] == 0x00) && (ep->emm[7] == 0x00) && (ep->emm[8] == 0x04) && (ep->emm[9] == 0x84))
{
if(i != -1)
{
ep->type = GLOBAL;
return 1;
}
}
if(i != -1)
{
ep->type = SHARED;
return (!memcmp(rdr->sa[i], ep->hexserial, 3));
}
return 0;
case 0x83:
memset(ep->hexserial, 0x00, 0x08);
ep->hexserial[0] = ep->emm[5];
ep->hexserial[1] = ep->emm[4];
ep->hexserial[2] = ep->emm[3];
ep->hexserial[3] = ep->emm[6];
if(ep->emm[7] == 0x10)
{
ep->type = SHARED;
for(i = 0; i < rdr->nprov; i++)
{
if(!memcmp(rdr->sa[i], "\x00\x00\x00", 3))
{
continue;
}
if(!memcmp(rdr->sa[i], ep->hexserial, 0x03))
{
return 1;
}
}
}
else if (!memcmp(rdr->hexserial + 2, ep->hexserial, 0x04))
{
ep->type = UNIQUE;
return 1;
}
else if ((ep->emm[5] == 0x04) && (ep->emm[6] == 0x70))
{
ep->type = GLOBAL;
return 1;
}
return 0;
case 0x87:
memset(ep->hexserial, 0x00, 0x08);
ep->hexserial[0] = ep->emm[5];
ep->hexserial[1] = ep->emm[4];
ep->hexserial[2] = ep->emm[3];
ep->hexserial[3] = ep->emm[6];
ep->type = SHARED;
for(i = 0; i < rdr->nprov; i++)
{
if(!memcmp(rdr->sa[i], "\x00\x00\x00", 3))
{
continue;
}
if(!memcmp(rdr->sa[i], ep->hexserial, 0x03))
{
return 1;
}
}
return 0;
default:
ep->type = UNKNOWN;
return 0;
}
}
}
int32_t nagra_get_emm_filter(struct s_reader *rdr, struct s_csystem_emm_filter **emm_filters, unsigned int *filter_count)
{
#ifdef READER_NAGRA_MERLIN
if(rdr->cak7type == 3)
{
if(*emm_filters == NULL)
{
const unsigned int max_filter_count = 2 + (2 * rdr->nprov);
if(!cs_malloc(emm_filters, max_filter_count * sizeof(struct s_csystem_emm_filter)))
{
return ERROR;
}
struct s_csystem_emm_filter *filters = *emm_filters;
*filter_count = 0;
int32_t idx = 0;
if(rdr->emm83 == 1)
{
filters[idx].type = EMM_GLOBAL;
filters[idx].enabled = 1;
filters[idx].filter[0] = 0x83;
filters[idx].mask[0] = 0xFF;
idx++;
}
int32_t i;
for(i = 0; i < rdr->nemm82u; i++)
{
filters[idx].type = EMM_UNIQUE;
filters[idx].enabled = 1;
memcpy(&filters[idx].filter[0], rdr->emm82u[i], 7);
memset(&filters[idx].mask[0], 0xFF, 7);
idx++;
}
for(i = 0; i < rdr->nemm84s; i++)
{
filters[idx].type = EMM_SHARED;
filters[idx].enabled = 1;
memcpy(&filters[idx].filter[0], rdr->emm84s[i], 6);
memset(&filters[idx].mask[0], 0xFF, 6);
idx++;
}
if(rdr->cwpkcaid_length && rdr->nuid_length)
{
filters[idx].type = EMM_UNIQUE;
filters[idx].enabled = 1;
filters[idx].filter[0] = 0x90;
filters[idx].filter[1] = rdr->nuid[2];
filters[idx].filter[2] = rdr->nuid[1];
filters[idx].filter[3] = rdr->nuid[0];
filters[idx].filter[4] = rdr->nuid[3];
memset(&filters[idx].mask[0], 0xFF, 5);
idx++;
}
*filter_count = idx;
}
return OK;
}
else if(rdr->cak7type == 1)
{
if(*emm_filters == NULL)
{
const unsigned int max_filter_count = 2 + (4 * rdr->nprov);
if(!cs_malloc(emm_filters, max_filter_count * sizeof(struct s_csystem_emm_filter)))
{
return ERROR;
}
struct s_csystem_emm_filter *filters = *emm_filters;
*filter_count = 0;
int32_t idx = 0;
if(rdr->emm82 == 1)
{
filters[idx].type = EMM_GLOBAL;
filters[idx].enabled = 1;
filters[idx].filter[0] = 0x82;
filters[idx].mask[0] = 0xFF;
idx++;
}
int32_t i;
for(i = 0; i < rdr->nemm83u; i++)
{
filters[idx].type = EMM_UNIQUE;
filters[idx].enabled = 1;
memcpy(&filters[idx].filter[0], rdr->emm83u[i], 6);
memset(&filters[idx].mask[0], 0xFF, 6);
idx++;
}
for(i = 0; i < rdr->nemm83s; i++)
{
filters[idx].type = EMM_SHARED;
filters[idx].enabled = 1;
memcpy(&filters[idx].filter[0], rdr->emm83s[i], 6);
memset(&filters[idx].mask[0], 0xFF, 6);
idx++;
}
for(i = 0; i < rdr->nemm84; i++)
{
filters[idx].type = EMM_GLOBAL;
filters[idx].enabled = 1;
memcpy(&filters[idx].filter[0], rdr->emm84[i], 3);
memset(&filters[idx].mask[0], 0xFF, 3);
idx++;
}
for(i = 0; i < rdr->nemm87; i++)
{
filters[idx].type = EMM_SHARED;
filters[idx].enabled = 1;
memcpy(&filters[idx].filter[0], rdr->emm87[i], 6);
memset(&filters[idx].mask[0], 0xFF, 6);
idx++;
}
if(rdr->cwpkcaid_length && rdr->nuid_length)
{
filters[idx].type = EMM_UNIQUE;
filters[idx].enabled = 1;
filters[idx].filter[0] = 0x90;
filters[idx].filter[1] = rdr->nuid[2];
filters[idx].filter[2] = rdr->nuid[1];
filters[idx].filter[3] = rdr->nuid[0];
filters[idx].filter[4] = rdr->nuid[3];
memset(&filters[idx].mask[0], 0xFF, 5);
idx++;
}
*filter_count = idx;
}
return OK;
}
else
#endif
{
if(*emm_filters == NULL)
{
const unsigned int max_filter_count = 4 + (4 * rdr->nprov);
if(!cs_malloc(emm_filters, max_filter_count * sizeof(struct s_csystem_emm_filter)))
{
return ERROR;
}
struct s_csystem_emm_filter *filters = *emm_filters;
*filter_count = 0;
int32_t idx = 0;
filters[idx].type = EMM_UNIQUE;
filters[idx].enabled = 1;
filters[idx].filter[0] = 0x82;
filters[idx].mask[0] = 0xFF;
memcpy(&filters[idx].filter[1], rdr->hexserial, 6);
memset(&filters[idx].mask[1], 0xFF, 6);
idx++;
filters[idx].type = EMM_UNIQUE;
filters[idx].enabled = 1;
filters[idx].filter[0] = 0x83;
filters[idx].filter[1] = rdr->hexserial[4];
filters[idx].filter[2] = rdr->hexserial[3];
filters[idx].filter[3] = rdr->hexserial[2];
filters[idx].filter[4] = rdr->hexserial[5];
filters[idx].filter[5] = 0x00;
memset(&filters[idx].mask[0], 0xFF, 6);
idx++;
filters[idx].type = EMM_GLOBAL;
filters[idx].enabled = 1;
filters[idx].filter[0] = 0x82;
filters[idx].mask[0] = 0xFF;
filters[idx].filter[1] = 0x00;
filters[idx].filter[2] = 0x00;
filters[idx].filter[3] = 0x00;
filters[idx].filter[4] = 0x00;
filters[idx].filter[5] = 0x00;
memset(&filters[idx].mask[1], 0xFF, 5);
idx++;
filters[idx].type = EMM_GLOBAL;
filters[idx].enabled = 1;
filters[idx].filter[0] = 0x83;
filters[idx].mask[0] = 0xFF;
filters[idx].filter[1] = 0x00;
filters[idx].filter[2] = 0x00;
memset(&filters[idx].mask[1], 0xFF, 2);
idx++;
int32_t prov;
for(prov = 0; prov < rdr->nprov; prov++)
{
filters[idx].type = EMM_GLOBAL;
filters[idx].enabled = 1;
filters[idx].filter[0] = 0x84;
filters[idx].mask[0] = 0xFF;
memcpy(&filters[idx].filter[1], &rdr->prid[prov][2], 2);
memset(&filters[idx].mask[1], 0xFF, 2);
filters[idx].filter[3] = 0x00;
filters[idx].filter[4] = 0x00;
filters[idx].filter[5] = 0x00;
memset(&filters[idx].mask[3], 0xFF, 3);
idx++;
if(!memcmp(rdr->sa[prov], "\x00\x00\x00", 3))
{
continue;
}
filters[idx].type = EMM_SHARED;
filters[idx].enabled = 1;
filters[idx].filter[0] = 0x84;
filters[idx].mask[0] = 0xFF;
memcpy(&filters[idx].filter[1], &rdr->prid[prov][2], 2);
memset(&filters[idx].mask[1], 0xFF, 2);
memcpy(&filters[idx].filter[3], &rdr->sa[prov], 3);
memset(&filters[idx].mask[3], 0xFF, 3);
idx++;
filters[idx].type = EMM_SHARED;
filters[idx].enabled = 1;
filters[idx].filter[0] = 0x83;
filters[idx].filter[1] = rdr->sa[prov][2];
filters[idx].filter[2] = rdr->sa[prov][1];
filters[idx].filter[3] = rdr->sa[prov][0];
filters[idx].filter[4] = 0x00;
filters[idx].filter[5] = 0x10;
memset(&filters[idx].mask[0], 0xFF, 6);
idx++;
filters[idx].type = EMM_SHARED;
filters[idx].enabled = 1;
filters[idx].filter[0] = 0x87;
filters[idx].filter[1] = rdr->sa[prov][2];
filters[idx].filter[2] = rdr->sa[prov][1];
filters[idx].filter[3] = rdr->sa[prov][0];
filters[idx].filter[4] = 0x00;
filters[idx].filter[5] = 0x00;
memset(&filters[idx].mask[0], 0xFF, 6);
idx++;
}
*filter_count = idx;
}
return OK;
}
}