bluray.c 6.95 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

Accident's avatar
 
Accident committed
13 14 15 16
#if HAVE_INTTYPES_H
#include <inttypes.h>
#endif

cRTrn13's avatar
cRTrn13 committed
17
#include <stdio.h>
cRTrn13's avatar
cRTrn13 committed
18

cRTrn13's avatar
cRTrn13 committed
19
#include "bluray.h"
cRTrn13's avatar
cRTrn13 committed
20
#include "util/macro.h"
cRTrn13's avatar
cRTrn13 committed
21
#include "util/logging.h"
22 23
#include "util/strutl.h"
#include "file/dl.h"
cRTrn13's avatar
cRTrn13 committed
24

cRTrn13's avatar
cRTrn13 committed
25 26
BLURAY *bd_open(const char* device_path, const char* keyfile_path)
{
27
    BLURAY *bd = calloc(1, sizeof(BLURAY));
cRTrn13's avatar
cRTrn13 committed
28

cRTrn13's avatar
cRTrn13 committed
29
    if (device_path) {
Accident's avatar
 
Accident committed
30 31

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

cRTrn13's avatar
cRTrn13 committed
33 34 35 36
        bd->aacs = NULL;
        bd->h_libaacs = NULL;
        bd->fp = NULL;

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

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

Accident's avatar
 
Accident committed
45
                fptr = dl_dlsym(bd->h_libaacs, "aacs_open");
46
                bd->aacs = fptr(device_path, keyfile_path);
cRTrn13's avatar
cRTrn13 committed
47
            } else {
48
                DEBUG(DBG_BLURAY, "libaacs not found!\n");
cRTrn13's avatar
cRTrn13 committed
49 50
            }
        } else {
cRTrn13's avatar
cRTrn13 committed
51
            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
52 53
        }

54 55 56 57

        // Take a quick stab to see if we want/need bdplus
        // we should fix this, and add various string functions.
        {
Accident's avatar
 
Accident committed
58 59 60
            uint8_t vid[16] = {
                0xC5,0x43,0xEF,0x2A,0x15,0x0E,0x50,0xC4,0xE2,0xCA,
                0x71,0x65,0xB1,0x7C,0xA7,0xCB}; // FIXME
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
            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);
        }


88

cRTrn13's avatar
Fix  
cRTrn13 committed
89
        DEBUG(DBG_BLURAY, "BLURAY initialized! (0x%08x)\n", bd);
cRTrn13's avatar
cRTrn13 committed
90
    } else {
cRTrn13's avatar
cRTrn13 committed
91 92
        X_FREE(bd);

cRTrn13's avatar
cRTrn13 committed
93
        DEBUG(DBG_BLURAY | DBG_CRIT, "No device path provided!\n");
cRTrn13's avatar
cRTrn13 committed
94 95 96 97 98 99 100
    }

    return bd;
}

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

105
        dl_dlclose(bd->h_libaacs);
cRTrn13's avatar
cRTrn13 committed
106 107
    }

108 109 110 111 112 113 114
    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
115

116 117
        bd->bdplus_seek  = NULL;
        bd->bdplus_fixup = NULL;
118
    }
cRTrn13's avatar
cRTrn13 committed
119

cRTrn13's avatar
cRTrn13 committed
120 121 122
    if (bd->fp) {
        file_close(bd->fp);
    }
cRTrn13's avatar
cRTrn13 committed
123

124 125
    X_FREE(bd->device_path);

cRTrn13's avatar
cRTrn13 committed
126
    DEBUG(DBG_BLURAY, "BLURAY destroyed! (0x%08x)\n", bd);
cRTrn13's avatar
cRTrn13 committed
127 128

    X_FREE(bd);
cRTrn13's avatar
cRTrn13 committed
129
}
cRTrn13's avatar
cRTrn13 committed
130

cRTrn13's avatar
cRTrn13 committed
131
uint64_t bd_seek(BLURAY *bd, uint64_t pos)
cRTrn13's avatar
cRTrn13 committed
132 133 134 135
{
    if (pos < bd->s_size) {
        bd->s_pos = pos - (pos % 6144);

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

138 139
        bd->int_buf_off = 6144;

Accident's avatar
 
Accident committed
140 141
        DEBUG(DBG_BLURAY, "Seek to %"PRIu64" (0x%08x)\n",
              bd->s_pos, bd);
142
        if (bd->bdplus_seek && bd->bdplus)
Accident's avatar
 
Accident committed
143
            bd->bdplus_seek(bd->bdplus, bd->s_pos);
144

cRTrn13's avatar
cRTrn13 committed
145 146 147 148 149 150 151
    }

    return bd->s_pos;
}

int bd_read(BLURAY *bd, unsigned char *buf, int len)
{
152
    if (bd->fp) {
153 154
        int out_len = 0;

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

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

Accident's avatar
 
Accident committed
162 163 164 165 166 167
                    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);
168

169
                                    return 0;
Accident's avatar
 
Accident committed
170 171 172
                                } // decrypt
                            } // dlsym
                        } // aacs
173

Accident's avatar
 
Accident committed
174
                        // bdplus fixup, if required.
Accident's avatar
 
Accident committed
175 176 177 178 179 180 181 182 183 184 185 186
                        if (bd->bdplus_fixup && bd->bdplus) {
                            int32_t numFixes;
                            numFixes = bd->bdplus_fixup(bd->bdplus,
                                                        len,
                                                        buf);
#if 0
                            if (numFixes) {
                                DEBUG(DBG_BLURAY,
                                      "BDPLUS did %u fixups\n", numFixes);
                            }
#endif
                        }
cRTrn13's avatar
cRTrn13 committed
187

Accident's avatar
 
Accident committed
188
                        bd->s_pos += len;
189

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

Accident's avatar
 
Accident committed
192 193 194
                        return len;
                    } // read
                } // int_buf
Accident's avatar
 
Accident committed
195 196
                        bd->int_buf_off = 0;

Accident's avatar
 
Accident committed
197 198 199
            } // while
        } // s_size
    } // if ->fp
200 201
    DEBUG(DBG_BLURAY, "No valid title selected! (0x%08x)\n", bd->s_pos);

cRTrn13's avatar
cRTrn13 committed
202 203
    return 0;
}
cRTrn13's avatar
cRTrn13 committed
204

205
int bd_select_title(BLURAY *bd, uint32_t title)
cRTrn13's avatar
cRTrn13 committed
206 207 208 209
{
    char f_name[100];

    memset(f_name, 0, sizeof(f_name));
Accident's avatar
 
Accident committed
210
    snprintf(f_name, 100, "%s/BDMV/STREAM/%05u.m2ts", bd->device_path, title);
cRTrn13's avatar
cRTrn13 committed
211 212 213 214 215 216 217

    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
218

219 220 221
            bd_seek(bd, 0);

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

223 224 225 226 227 228 229
            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
230 231
            return 1;
        }
232 233

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

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

cRTrn13's avatar
cRTrn13 committed
238 239
    return 0;
}
240 241 242 243 244

uint64_t bd_get_title_size(BLURAY *bd)
{
    return bd->s_size;
}
cRTrn13's avatar
cRTrn13 committed
245 246 247 248 249

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