bluray.c 6.8 KB
Newer Older
Accident's avatar
 
Accident committed
1 2 3 4 5 6 7 8 9 10 11
#if HAVE_CONFIG_H
#include "config.h"
#endif

#if HAVE_MALLOC_H
#include <malloc.h>
#endif

#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
cRTrn13's avatar
cRTrn13 committed
12

cRTrn13's avatar
cRTrn13 committed
13
#include <stdio.h>
cRTrn13's avatar
cRTrn13 committed
14

cRTrn13's avatar
cRTrn13 committed
15
#include "bluray.h"
cRTrn13's avatar
cRTrn13 committed
16
#include "util/macro.h"
cRTrn13's avatar
cRTrn13 committed
17
#include "util/logging.h"
18 19
#include "util/strutl.h"
#include "file/dl.h"
cRTrn13's avatar
cRTrn13 committed
20

cRTrn13's avatar
cRTrn13 committed
21 22
BLURAY *bd_open(const char* device_path, const char* keyfile_path)
{
23
    BLURAY *bd = calloc(1, sizeof(BLURAY));
cRTrn13's avatar
cRTrn13 committed
24

cRTrn13's avatar
cRTrn13 committed
25
    if (device_path) {
26
        strncpy(bd->device_path, device_path, 100); // <-- FIXME. bufrun,size,term
cRTrn13's avatar
cRTrn13 committed
27

cRTrn13's avatar
cRTrn13 committed
28 29 30 31
        bd->aacs = NULL;
        bd->h_libaacs = NULL;
        bd->fp = NULL;

cRTrn13's avatar
Fix  
cRTrn13 committed
32
        if (keyfile_path) {
33 34
            //if ((bd->h_libaacs = dlopen("libaacs.so", RTLD_LAZY))) {
            if ((bd->h_libaacs = dl_dlopen("aacs"))) {
cRTrn13's avatar
cRTrn13 committed
35 36 37
                fptr_p_void fptr;
                uint8_t *vid;

cRTrn13's avatar
cRTrn13 committed
38
                DEBUG(DBG_BLURAY, "Downloaded libaacs (0x%08x)\n", bd->h_libaacs);
cRTrn13's avatar
cRTrn13 committed
39

40 41
                fptr_p_void fptr = dl_dlsym(bd->h_libaacs, "aacs_open");
                bd->aacs = fptr(device_path, keyfile_path);
cRTrn13's avatar
cRTrn13 committed
42
            } else {
43
                DEBUG(DBG_BLURAY, "libaacs not found!\n");
cRTrn13's avatar
cRTrn13 committed
44 45
            }
        } else {
cRTrn13's avatar
cRTrn13 committed
46
            DEBUG(DBG_BLURAY | DBG_CRIT, "No keyfile provided. You will not be able to make use of crypto functionality (0x%08x)\n", bd);
cRTrn13's avatar
cRTrn13 committed
47 48
        }

49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80

        // Take a quick stab to see if we want/need bdplus
        // we should fix this, and add various string functions.
        {
            uint8_t vid[16] = {0}; // FIXME
            FILE_H *fd;
            char *tmp = NULL;
            tmp = str_printf("%s/BDSVM/00000.svm", bd->device_path);
            if ((fd = file_open(tmp, "rb"))) {
                file_close(fd);

                DEBUG(DBG_BDPLUS, "attempting to load libbdplus\n");
                if ((bd->h_libbdplus = dl_dlopen("bdplus"))) {
                    DEBUG(DBG_BLURAY, "Downloaded libbdplus (0x%08x)\n",
                          bd->h_libbdplus);

                    fptr_p_void bdplus_init = dl_dlsym(bd->h_libbdplus, "bdplus_init");
                    //bdplus_t *bdplus_init(path,configfile_path,*vid );
                    if (bdplus_init)
                        bd->bdplus = bdplus_init(device_path, keyfile_path, vid);

                    // Since we will call these functions a lot, we assign them
                    // now.
                    bd->bdplus_seek  = dl_dlsym(bd->h_libbdplus, "bdplus_seek");
                    bd->bdplus_fixup = dl_dlsym(bd->h_libbdplus, "bdplus_fixup");

                } // dlopen
            } // file_open
            X_FREE(tmp);
        }


81

cRTrn13's avatar
Fix  
cRTrn13 committed
82
        DEBUG(DBG_BLURAY, "BLURAY initialized! (0x%08x)\n", bd);
cRTrn13's avatar
cRTrn13 committed
83
    } else {
cRTrn13's avatar
cRTrn13 committed
84 85
        X_FREE(bd);

cRTrn13's avatar
cRTrn13 committed
86
        DEBUG(DBG_BLURAY | DBG_CRIT, "No device path provided!\n");
cRTrn13's avatar
cRTrn13 committed
87 88 89 90 91 92 93
    }

    return bd;
}

void bd_close(BLURAY *bd)
{
94 95 96
    if (bd->h_libaacs && bd->aacs) {
        fptr_p_void fptr = dl_dlsym(bd->h_libaacs, "aacs_close");
        fptr(bd->aacs);
cRTrn13's avatar
cRTrn13 committed
97

98
        dl_dlclose(bd->h_libaacs);
cRTrn13's avatar
cRTrn13 committed
99 100
    }

101 102 103 104 105 106 107
    if (bd->h_libbdplus && bd->bdplus) {
        fptr_p_void bdplus_free = dl_dlsym(bd->h_libbdplus, "bdplus_free");
        if (bdplus_free) bdplus_free(bd->bdplus);
        bd->bdplus = NULL;

        dl_dlclose(bd->h_libbdplus);
        bd->h_libbdplus = NULL;
cRTrn13's avatar
cRTrn13 committed
108

109 110
        bd->bdplus_seek  = NULL;
        bd->bdplus_fixup = NULL;
111
    }
cRTrn13's avatar
cRTrn13 committed
112

cRTrn13's avatar
cRTrn13 committed
113 114 115
    if (bd->fp) {
        file_close(bd->fp);
    }
cRTrn13's avatar
cRTrn13 committed
116

117 118
    X_FREE(bd->device_path);

cRTrn13's avatar
cRTrn13 committed
119
    DEBUG(DBG_BLURAY, "BLURAY destroyed! (0x%08x)\n", bd);
cRTrn13's avatar
cRTrn13 committed
120 121

    X_FREE(bd);
cRTrn13's avatar
cRTrn13 committed
122
}
cRTrn13's avatar
cRTrn13 committed
123

cRTrn13's avatar
cRTrn13 committed
124
uint64_t bd_seek(BLURAY *bd, uint64_t pos)
cRTrn13's avatar
cRTrn13 committed
125 126 127 128
{
    if (pos < bd->s_size) {
        bd->s_pos = pos - (pos % 6144);

cRTrn13's avatar
cRTrn13 committed
129
        file_seek(bd->fp, bd->s_pos, SEEK_SET);
130

cRTrn13's avatar
cRTrn13 committed
131 132 133 134 135
        if (bd->h_libbdplus && bd->bdplus) {
            fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_seek");
            fptr(bd->bdplus, bd->s_pos);
        }

136 137
        bd->int_buf_off = 6144;

138
        DEBUG(DBG_BLURAY, "Seek to %ld (0x%08x)\n", bd->s_pos, bd);
139 140 141
        if (bd->bdplus_seek && bd->bdplus)
            bd->bdplus_seek(bd->bdplus, pos);

cRTrn13's avatar
cRTrn13 committed
142 143 144 145 146 147 148
    }

    return bd->s_pos;
}

int bd_read(BLURAY *bd, unsigned char *buf, int len)
{
149
    if (bd->fp) {
150 151
        int out_len = 0;

152 153
        DEBUG(DBG_BLURAY, "Reading unit [%d bytes] at %ld... (0x%08x)\n", len, bd->s_pos, bd);

hpi1's avatar
hpi1 committed
154
        if (len + bd->s_pos <= bd->s_size) {
155 156 157
            while (out_len < len) {
                if (bd->int_buf_off == 6144) {
                    int read_len;
158

159 160 161 162 163 164
            if ((read_len = file_read(bd->fp, buf, len))) {
                if (bd->h_libaacs && bd->aacs) {
                    // FIXME: calling dlsym for every read() call.
                    if ((bd->libaacs_decrypt_unit = dl_dlsym(bd->h_libaacs, "aacs_decrypt_unit"))) {
                        if (!bd->libaacs_decrypt_unit(bd->aacs, buf, len, bd->s_pos)) {
                            DEBUG(DBG_BLURAY, "Unable decrypt unit! (0x%08x)\n", bd);
165

166 167
                                    return 0;
                                }
cRTrn13's avatar
cRTrn13 committed
168

169 170 171 172 173
                                if (bd->h_libbdplus && bd->bdplus) {
                                    fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_fixup");
                                    fptr(bd->bdplus, bd->int_buf, read_len);
                                }
                            }
cRTrn13's avatar
cRTrn13 committed
174
                        }
175
                    }
176
                    bd->int_buf_off = 0;
cRTrn13's avatar
cRTrn13 committed
177 178
                }

179 180 181 182
                if (bd->bdplus_fixup && bd->bdplus)
                    bd->bdplus_fixup(bd->bdplus, len, buf);

                bd->s_pos += len;
cRTrn13's avatar
cRTrn13 committed
183

184
            bd->s_pos += len;
185

186 187 188
            DEBUG(DBG_BLURAY, "%d bytes read OK! (0x%08x)\n", len, bd);

            return len;
cRTrn13's avatar
cRTrn13 committed
189 190 191
        }
    }

192 193
    DEBUG(DBG_BLURAY, "No valid title selected! (0x%08x)\n", bd->s_pos);

cRTrn13's avatar
cRTrn13 committed
194 195
    return 0;
}
cRTrn13's avatar
cRTrn13 committed
196

197
int bd_select_title(BLURAY *bd, uint32_t title)
cRTrn13's avatar
cRTrn13 committed
198 199 200 201 202 203 204 205 206 207 208 209
{
    char f_name[100];

    memset(f_name, 0, sizeof(f_name));
    snprintf(f_name, 100, "%s/BDMV/STREAM/%05ld.m2ts", bd->device_path, title);

    bd->s_size = 0;
    bd->s_pos = 0;

    if ((bd->fp = file_open(f_name, "rb"))) {
        file_seek(bd->fp, 0, SEEK_END);
        if ((bd->s_size = file_tell(bd->fp))) {
cRTrn13's avatar
cRTrn13 committed
210 211 212 213 214
            if (bd->h_libbdplus && bd->bdplus) {
                fptr_p_void fptr = dlsym(bd->h_libbdplus, "bdplus_set_title");
                fptr(bd->bdplus, title);
            }

215 216 217
            bd_seek(bd, 0);

            DEBUG(DBG_BLURAY, "Title %s selected! (0x%08x)\n", f_name, bd);
cRTrn13's avatar
cRTrn13 committed
218

219 220 221 222 223 224 225
            if (bd->h_libbdplus && bd->bdplus) {
                fptr_p_void bdplus_set_title;
                bdplus_set_title = dl_dlsym(bd->h_libbdplus, "bdplus_set_title");
                if (bdplus_set_title)
                    bdplus_set_title(bd->bdplus, title);
            }

cRTrn13's avatar
cRTrn13 committed
226 227
            return 1;
        }
228 229

        DEBUG(DBG_BLURAY, "Title %s empty! (0x%08x)\n", f_name, bd);
cRTrn13's avatar
cRTrn13 committed
230 231
    }

cRTrn13's avatar
cRTrn13 committed
232
    DEBUG(DBG_BLURAY | DBG_CRIT, "Unable to select title %s! (0x%08x)\n", f_name, bd);
233

cRTrn13's avatar
cRTrn13 committed
234 235
    return 0;
}
236 237 238 239 240

uint64_t bd_get_title_size(BLURAY *bd)
{
    return bd->s_size;
}
cRTrn13's avatar
cRTrn13 committed
241 242 243 244 245

uint64_t bd_tell(BLURAY *bd)
{
    return bd->s_pos;
}