void stapi_off(void) {
	int32_t i;

	pthread_mutex_lock(&filter_lock);

	cs_log("stapi shutdown");

	disable_pmt_files=1;
	stapi_on=0;

	for (i=0;i<MAX_DEMUX;i++)
		dvbapi_stop_descrambling(i);

	for (i=0;i<PTINUM;i++) {
		if (dev_list[i].SessionHandle>0) {
			if (dev_list[i].SignalHandle > 0) {
				oscam_stapi_SignalAbort(dev_list[i].SignalHandle);
			}
			pthread_cancel(dev_list[i].thread);
		}
	}

	pthread_mutex_unlock(&filter_lock);
	sleep(2);
	return;
}
void stapi_off(void) {
	int32_t i;

	pthread_mutex_lock(&filter_lock);

	cs_log("stapi shutdown");

	disable_pmt_files=1;
	stapi_on=0;
	char dest[1024];
	for (i=0;i<MAX_DEMUX;i++){
		snprintf(dest, sizeof(dest), "%s%s", TMPDIR, demux[i].pmt_file);
		unlink(dest); // remove obsolete pmt file
		dvbapi_stop_descrambling(i);
	}

	for (i=0;i<PTINUM;i++) {
		if (dev_list[i].SessionHandle>0) {
			if (dev_list[i].SignalHandle > 0) {
				oscam_stapi_SignalAbort(dev_list[i].SignalHandle);
			}
			pthread_cancel(dev_list[i].thread);
		}
	}

	pthread_mutex_unlock(&filter_lock);
	sleep(2);
	return;
}
int32_t stapi_set_filter(int32_t demux_id, uint16_t pid, uchar *filter, uchar *mask, int32_t num, char *pmtfile)
{
    int32_t i;
    int32_t ret = -1;
    char dest[1024];
    uint16_t pids[1] = { pid };
    struct s_dvbapi_priority *p;

    if(!pmtfile)
    {
        cs_log_dbg(D_DVBAPI, "No valid pmtfile!");
        return -1;
    }

    cs_log_dbg(D_DVBAPI, "pmt file %s demux_id %d", pmtfile, demux_id);

    for(p = dvbapi_priority; p != NULL; p = p->next)
    {
        if(p->type != 's') {
            continue;    // stapi rule?
        }
        if(strcmp(pmtfile, p->pmtfile) != 0) {
            continue;    // same file?
        }

        for(i = 0; i < PTINUM; i++)
        {
            if(strcmp(dev_list[i].name, p->devname) == 0 && p->disablefilter == 0)  // check device name and if filtering is enabled!
            {
                cs_log_dbg(D_DVBAPI, "set stapi filter on %s for pid %04X", dev_list[i].name, pids[0]);
                ret = stapi_do_set_filter(demux_id, &dev_list[i].demux_fd[demux_id][num], pids, 1, filter, mask, i);
                if(ret > 0)    // success
                {
                    demux[demux_id].dev_index = i;
                    cs_log_dbg(D_DVBAPI, "%s filter %d set (pid %04X)", dev_list[i].name, num, pid);
                    return ret; // return filternumber
                }
                else   // failure
                {
                    cs_log_dbg(D_DVBAPI, "Error setting new filter for pid %04X on %s!", pid, dev_list[i].name);
                    return -1; // set return to error
                }
            }
        }
    }

    if(p == NULL)
    {
        cs_log_dbg(D_DVBAPI, "No matching S: line in oscam.dvbapi for pmtfile %s -> stop descrambling!", pmtfile);
        snprintf(dest, sizeof(dest), "%s%s", TMPDIR, demux[demux_id].pmt_file);
        unlink(dest); // remove obsolete pmt file
        dvbapi_stop_descrambling(demux_id);
    }
    return ret;
}
static void stapi_off(void)
{
    int32_t i;
    uint32_t ErrorCode;

    SAFE_MUTEX_LOCK(&filter_lock);

    cs_log("stapi shutdown");

    disable_pmt_files = 1;
    stapi_on = 0;
    for(i = 0; i < MAX_DEMUX; i++)
    {
        dvbapi_stop_descrambling(i);

        if (tkd_desc_info[i].path_hndl != 0)
        {
            ErrorCode = oscam_sttkd_Deallocate(tkd_desc_info[i].path_hndl, tkd_desc_info[i].key_hndl);
            if (ErrorCode != 0)
            {
                cs_log("oscam_sttkd_Deallocate faild! ErrorCode: %d", ErrorCode);
            }
        }
    }

    uint8_t TKD_InstanceID = 0;
    for(TKD_InstanceID = 0; TKD_InstanceID < TKD_MAX_NUMBER; TKD_InstanceID++)
    {
        ErrorCode = oscam_sttkd_Close(TKDHandle[TKD_InstanceID]);
        if(ErrorCode != 0)
        {
            cs_log("oscam_sttkd_Close: ErrorCode: %d TKDHandle: 0x%08X", ErrorCode, TKDHandle[TKD_InstanceID]);
        }
    }

    for(i = 0; i < PTINUM; i++)
    {
        if(dev_list[i].SessionHandle > 0)
        {
            if(dev_list[i].SignalHandle > 0)
            {
                oscam_stapi5_SignalAbort(dev_list[i].SignalHandle);
            }
            pthread_cancel(dev_list[i].thread);
        }
    }

    SAFE_MUTEX_UNLOCK(&filter_lock);
    sleep(2);
    return;
}