Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Introduce DVB CA support
- Loading branch information
Showing
9 changed files
with
842 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,222 @@ | ||
| /* | ||
| * tvheadend, DVB CAM interface | ||
| * Copyright (C) 2014 Damjan Marion | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation, either version 3 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 General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
|
|
||
| #include <ctype.h> | ||
| #include "tvheadend.h" | ||
| #include "caclient.h" | ||
| #include "service.h" | ||
| #include "input.h" | ||
|
|
||
| #include "dvbcam.h" | ||
| #include "input/mpegts/linuxdvb/linuxdvb_private.h" | ||
|
|
||
| #if ENABLE_LINUXDVB_CA | ||
|
|
||
| #define CAIDS_PER_CA_SLOT 16 | ||
|
|
||
| typedef struct dvbcam_active_service { | ||
| TAILQ_ENTRY(dvbcam_active_service) link; | ||
| service_t *t; | ||
| uint8_t *last_pmt; | ||
| int last_pmt_len; | ||
| linuxdvb_ca_t *ca; | ||
| uint8_t slot; | ||
| } dvbcam_active_service_t; | ||
|
|
||
| typedef struct dvbcam_active_caid { | ||
| TAILQ_ENTRY(dvbcam_active_caid) link; | ||
| uint16_t caids[CAIDS_PER_CA_SLOT]; | ||
| int num_caids; | ||
| linuxdvb_ca_t *ca; | ||
| uint8_t slot; | ||
| } dvbcam_active_caid_t; | ||
|
|
||
| TAILQ_HEAD(,dvbcam_active_service) dvbcam_active_services; | ||
| TAILQ_HEAD(,dvbcam_active_caid) dvbcam_active_caids; | ||
|
|
||
| pthread_mutex_t dvbcam_mutex; | ||
|
|
||
| void | ||
| dvbcam_register_cam(linuxdvb_ca_t * lca, uint8_t slot, uint16_t * caids, | ||
| int num_caids) | ||
| { | ||
| dvbcam_active_caid_t *ac; | ||
|
|
||
| num_caids = MIN(CAIDS_PER_CA_SLOT, num_caids); | ||
|
|
||
| if ((ac = malloc(sizeof(*ac))) == NULL) | ||
| return; | ||
|
|
||
| ac->ca = lca; | ||
| ac->slot = slot; | ||
| memcpy(ac->caids, caids, num_caids * sizeof(uint16_t)); | ||
| ac->num_caids = num_caids; | ||
|
|
||
| pthread_mutex_lock(&dvbcam_mutex); | ||
|
|
||
| TAILQ_INSERT_TAIL(&dvbcam_active_caids, ac, link); | ||
|
|
||
| pthread_mutex_unlock(&dvbcam_mutex); | ||
| } | ||
|
|
||
| void | ||
| dvbcam_unregister_cam(linuxdvb_ca_t * lca, uint8_t slot) | ||
| { | ||
| dvbcam_active_caid_t *ac, *ac_tmp; | ||
| dvbcam_active_service_t *as; | ||
|
|
||
| pthread_mutex_lock(&dvbcam_mutex); | ||
|
|
||
| /* remove pointer to this CAM in all active services */ | ||
| TAILQ_FOREACH(as, &dvbcam_active_services, link) | ||
| if (as->ca == lca && as->slot == slot) | ||
| as->ca = NULL; | ||
|
|
||
| /* delete entry */ | ||
| for (ac = TAILQ_FIRST(&dvbcam_active_caids); ac != NULL; ac = ac_tmp) { | ||
| ac_tmp = TAILQ_NEXT(ac, link); | ||
| if(ac && ac->ca == lca && ac->slot == slot) { | ||
| TAILQ_REMOVE(&dvbcam_active_caids, ac, link); | ||
| free(ac); | ||
| } | ||
| } | ||
|
|
||
| pthread_mutex_unlock(&dvbcam_mutex); | ||
| } | ||
|
|
||
| void | ||
| dvbcam_pmt_data(mpegts_service_t *s, const uint8_t *ptr, int len) | ||
| { | ||
| linuxdvb_frontend_t *lfe; | ||
| dvbcam_active_caid_t *ac; | ||
| dvbcam_active_service_t *as = NULL, *as2; | ||
| int i, l; | ||
| uint8_t *p; | ||
|
|
||
| lfe = (linuxdvb_frontend_t*) s->s_dvb_active_input; | ||
|
|
||
| if (!lfe) | ||
| return; | ||
|
|
||
| pthread_mutex_lock(&dvbcam_mutex); | ||
|
|
||
| TAILQ_FOREACH(as2, &dvbcam_active_services, link) | ||
| if (as2->t == (service_t *) s) { | ||
| as = as2; | ||
| break; | ||
| } | ||
|
|
||
| pthread_mutex_unlock(&dvbcam_mutex); | ||
|
|
||
| if (!as) | ||
| return; | ||
|
|
||
| if(as->last_pmt) | ||
| free(as->last_pmt); | ||
|
|
||
| as->last_pmt = malloc(len + 3); | ||
| memcpy(as->last_pmt, ptr-3, len + 3); | ||
| as->last_pmt_len = len + 3; | ||
| as->ca = NULL; | ||
|
|
||
| l = (ptr[7] & 0x03 )| ptr[8]; | ||
| p = (uint8_t *) ptr + 9; | ||
|
|
||
| while (l > 0 ) { | ||
| uint8_t desc_tag = p[0]; | ||
| uint8_t desc_len = p[1]; | ||
|
|
||
| if (desc_tag == DVB_DESC_CA) { | ||
| uint16_t caid = (p[2] << 8) | p[3]; | ||
|
|
||
| pthread_mutex_lock(&dvbcam_mutex); | ||
|
|
||
| TAILQ_FOREACH(ac, &dvbcam_active_caids, link) { | ||
| for(i=0;i<ac->num_caids;i++) { | ||
| if(ac->ca && ac->ca->lca_adapter == lfe->lfe_adapter && | ||
| ac->caids[i] == caid) | ||
| { | ||
| as->ca = ac->ca; | ||
| as->slot = ac->slot; | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| pthread_mutex_unlock(&dvbcam_mutex); | ||
| } | ||
| p += desc_len + 2; | ||
| l -= desc_len + 2; | ||
| } | ||
|
|
||
| /* this service doesn't have assigned CAM */ | ||
| if (!as->ca) | ||
| return; | ||
|
|
||
| linuxdvb_ca_send_capmt(as->ca, as->slot, as->last_pmt, as->last_pmt_len); | ||
| } | ||
|
|
||
| void | ||
| dvbcam_service_start(service_t *t) | ||
| { | ||
| dvbcam_active_service_t *as; | ||
|
|
||
| TAILQ_FOREACH(as, &dvbcam_active_services, link) | ||
| if (as->t == t) | ||
| return; | ||
|
|
||
| if ((as = malloc(sizeof(*as))) == NULL) | ||
| return; | ||
|
|
||
| as->t = t; | ||
| as->last_pmt = NULL; | ||
| as->last_pmt_len = 0; | ||
|
|
||
| pthread_mutex_lock(&dvbcam_mutex); | ||
| TAILQ_INSERT_TAIL(&dvbcam_active_services, as, link); | ||
| pthread_mutex_unlock(&dvbcam_mutex); | ||
| } | ||
|
|
||
| void | ||
| dvbcam_service_stop(service_t *t) | ||
| { | ||
| dvbcam_active_service_t *as, *as_tmp; | ||
|
|
||
| pthread_mutex_lock(&dvbcam_mutex); | ||
|
|
||
| for (as = TAILQ_FIRST(&dvbcam_active_services); as != NULL; as = as_tmp) { | ||
| as_tmp = TAILQ_NEXT(as, link); | ||
| if(as && as->t == t) { | ||
| TAILQ_REMOVE(&dvbcam_active_services, as, link); | ||
| if(as->last_pmt) | ||
| free(as->last_pmt); | ||
| free(as); | ||
| } | ||
| } | ||
|
|
||
| pthread_mutex_unlock(&dvbcam_mutex); | ||
| } | ||
|
|
||
| void | ||
| dvbcam_init(void) | ||
| { | ||
| pthread_mutex_init(&dvbcam_mutex, NULL); | ||
| TAILQ_INIT(&dvbcam_active_services); | ||
| TAILQ_INIT(&dvbcam_active_caids); | ||
| } | ||
|
|
||
| #endif /* ENABLE_LINUXDVB_CA */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| /* | ||
| * tvheadend - CSA wrapper | ||
| * Copyright (C) 2013 Adam Sutton | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation, either version 3 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 General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
|
|
||
| #ifndef __DVBCAM_H__ | ||
| #define __DVBCAM_H__ | ||
|
|
||
| struct mpegts_service; | ||
| struct elementary_stream; | ||
|
|
||
| #if ENABLE_LINUXDVB_CA | ||
|
|
||
| typedef struct linuxdvb_ca linuxdvb_ca_t; | ||
| void dvbcam_init(void); | ||
| void dvbcam_service_start(struct service *t); | ||
| void dvbcam_service_stop(struct service *t); | ||
| void dvbcam_register_cam(linuxdvb_ca_t * lca, uint8_t slot, uint16_t * caids, int num_caids); | ||
| void dvbcam_unregister_cam(linuxdvb_ca_t * lca, uint8_t slot); | ||
| void dvbcam_pmt_data(mpegts_service_t *s, const uint8_t *ptr, int len); | ||
|
|
||
| #endif | ||
|
|
||
| #endif /* __DVBCAM_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.