bluray.c 6.36 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) {
Accident's avatar
 
Accident committed
26 27

        bd->device_path = strdup(device_path);
cRTrn13's avatar
cRTrn13 committed
28

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

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

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

Accident's avatar
 
Accident committed
41
                fptr = dl_dlsym(bd->h_libaacs, "aacs_open");
42
                bd->aacs = fptr(device_path, keyfile_path);
cRTrn13's avatar
cRTrn13 committed
43
            } else {
44
                DEBUG(DBG_BLURAY, "libaacs not found!\n");
cRTrn13's avatar
cRTrn13 committed
45 46
            }
        } else {
cRTrn13's avatar
cRTrn13 committed
47
            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
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 81

        // 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);
        }


82

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

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

    return bd;
}

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

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

102 103 104 105 106 107 108
    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
109

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

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

118 119
    X_FREE(bd->device_path);

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

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

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

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

132 133
        bd->int_buf_off = 6144;

134
        DEBUG(DBG_BLURAY, "Seek to %ld (0x%08x)\n", bd->s_pos, bd);
135 136 137
        if (bd->bdplus_seek && bd->bdplus)
            bd->bdplus_seek(bd->bdplus, pos);

cRTrn13's avatar
cRTrn13 committed
138 139 140 141 142 143 144
    }

    return bd->s_pos;
}

int bd_read(BLURAY *bd, unsigned char *buf, int len)
{
145
    if (bd->fp) {
146 147
        int out_len = 0;

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

hpi1's avatar
hpi1 committed
150
        if (len + bd->s_pos <= bd->s_size) {
151 152 153
            while (out_len < len) {
                if (bd->int_buf_off == 6144) {
                    int read_len;
154

Accident's avatar
 
Accident committed
155 156 157 158 159 160
                    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);
161

162
                                    return 0;
Accident's avatar
 
Accident committed
163 164 165 166
                                } // decrypt
                            } // dlsym
                        } // aacs
                        bd->int_buf_off = 0;
167

Accident's avatar
 
Accident committed
168 169 170
                        // bdplus fixup, if required.
                        if (bd->bdplus_fixup && bd->bdplus)
                            bd->bdplus_fixup(bd->bdplus, len, buf);
cRTrn13's avatar
cRTrn13 committed
171

Accident's avatar
 
Accident committed
172
                        bd->s_pos += len;
173

Accident's avatar
 
Accident committed
174
                        DEBUG(DBG_BLURAY, "%d bytes read OK! (0x%08x)\n", len, bd);
cRTrn13's avatar
cRTrn13 committed
175

Accident's avatar
 
Accident committed
176 177 178 179 180 181
                        return len;
                    } // read
                } // int_buf
            } // while
        } // s_size
    } // if ->fp
182 183
    DEBUG(DBG_BLURAY, "No valid title selected! (0x%08x)\n", bd->s_pos);

cRTrn13's avatar
cRTrn13 committed
184 185
    return 0;
}
cRTrn13's avatar
cRTrn13 committed
186

187
int bd_select_title(BLURAY *bd, uint32_t title)
cRTrn13's avatar
cRTrn13 committed
188 189 190 191 192 193 194 195 196 197 198 199
{
    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
200

201 202 203
            bd_seek(bd, 0);

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

205 206 207 208 209 210 211
            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
212 213
            return 1;
        }
214 215

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

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

cRTrn13's avatar
cRTrn13 committed
220 221
    return 0;
}
222 223 224 225 226

uint64_t bd_get_title_size(BLURAY *bd)
{
    return bd->s_size;
}
cRTrn13's avatar
cRTrn13 committed
227 228 229 230 231

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