1 /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
2
3 /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens
4 Copyright (c) 2006 - 2016 Thomas Schmitt <scdbackup@gmx.net>
5 Provided under GPL version 2 or later.
6 */
7
8 #ifdef HAVE_CONFIG_H
9 #include "../config.h"
10 #endif
11
12 #include <stdio.h>
13
14 /* ts A61010 */
15 /* #include <a ssert.h> */
16
17 #include <unistd.h>
18 #include <string.h>
19 #include "error.h"
20 #include "options.h"
21 #include "transport.h"
22 #include "libburn.h"
23 #include "drive.h"
24 #include "sector.h"
25 #include "crc.h"
26 #include "debug.h"
27 #include "toc.h"
28 #include "write.h"
29
30 #include "libdax_msgs.h"
31 extern struct libdax_msgs *libdax_messenger;
32
33 #include "ecma130ab.h"
34
35
36 #ifdef Libburn_log_in_and_out_streaM
37 /* ts A61031 */
38 #include <sys/types.h>
39 #include <sys/stat.h>
40 #include <fcntl.h>
41 #endif /* Libburn_log_in_and_out_streaM */
42
43 /* ts B41126 : O_BINARY is needed for Cygwin but undefined elsewhere */
44 #ifndef O_BINARY
45 #define O_BINARY 0
46 #endif
47
48 /*static unsigned char isrc[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";*/
49
50 #define sector_common(X) d->alba++; d->rlba X;
51
uncook_subs(unsigned char * dest,unsigned char * source)52 static void uncook_subs(unsigned char *dest, unsigned char *source)
53 {
54 int i, j, code;
55
56 memset(dest, 0, 96);
57
58 for (i = 0; i < 12; i++) {
59 for (j = 0; j < 8; j++) {
60 for (code = 0; code < 8; code++) {
61 if (source[code * 12 + i] & 0x80)
62 dest[j + i * 8] |= (1 << (7 - code));
63 source[code * 12 + i] <<= 1;
64 }
65 }
66 }
67 }
68
69 /* @return >=0 : valid , <0 invalid */
sector_get_outmode(enum burn_write_types write_type,enum burn_block_types block_type)70 int sector_get_outmode(enum burn_write_types write_type,
71 enum burn_block_types block_type)
72 {
73 /* ts A61103 : extended SAO condition to TAO */
74 if (write_type == BURN_WRITE_SAO || write_type == BURN_WRITE_TAO)
75 return 0;
76 else
77 switch (block_type) {
78 case BURN_BLOCK_RAW0:
79 return BURN_MODE_RAW;
80 case BURN_BLOCK_RAW16:
81 return BURN_MODE_RAW | BURN_SUBCODE_P16;
82 case BURN_BLOCK_RAW96P:
83 return BURN_MODE_RAW | BURN_SUBCODE_P96;
84 case BURN_BLOCK_RAW96R:
85 return BURN_MODE_RAW | BURN_SUBCODE_R96;
86 case BURN_BLOCK_MODE1:
87 return BURN_MODE1;
88 default:
89 return -1;
90 }
91
92 /* ts A61007 : now handled in burn_write_opts_set_write_type() */
93 /* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */
94 }
95
96 /* 0 means "same as inmode" */
get_outmode(struct burn_write_opts * o)97 static int get_outmode(struct burn_write_opts *o)
98 {
99 /* ts A61007 */
100 return sector_get_outmode(o->write_type, o->block_type);
101
102 /* -1 is prevented by check in burn_write_opts_set_write_type() */
103 /* a ssert(0); */ /* return BURN_MODE_UNIMPLEMENTED :) */
104 }
105
106
get_bytes(struct burn_track * track,int count,unsigned char * data)107 static void get_bytes(struct burn_track *track, int count, unsigned char *data)
108 {
109 int valid, shortage, curr, i, tr;
110
111 #ifdef Libburn_log_in_and_out_streaM
112 /* ts A61031 */
113 static int tee_fd= -1;
114 if(tee_fd==-1)
115 tee_fd= open("/tmp/libburn_sg_readin",
116 O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
117 S_IRUSR | S_IWUSR);
118 #endif /* Libburn_log_in_and_out_streaM */
119
120
121 /* no track pointer means we're just generating 0s */
122 if (!track) {
123 memset(data, 0, count);
124 return;
125 }
126
127 /* first we use up any offset */
128 valid = track->offset - track->offsetcount;
129 if (valid > count)
130 valid = count;
131
132 if (valid) {
133 track->offsetcount += valid;
134 memset(data, 0, valid);
135 }
136 shortage = count - valid;
137
138 if (!shortage)
139 goto ex;
140
141 /* Next we use source data */
142 curr = valid;
143 if (!track->eos) {
144 if (track->source->read != NULL)
145 valid = track->source->read(track->source,
146 data + curr, count - curr);
147 else
148 valid = track->source->read_xt(track->source,
149 data + curr, count - curr);
150 } else valid = 0;
151
152 if (valid <= 0) { /* ts A61031 : extended from (valid == -1) */
153 track->eos = 1;
154 valid = 0;
155 }
156 track->sourcecount += valid;
157
158 #ifdef Libburn_log_in_and_out_streaM
159 /* ts A61031 */
160 if(tee_fd!=-1 && valid>0) {
161 write(tee_fd, data + curr, valid);
162 }
163 #endif /* Libburn_log_in_and_out_streaM */
164
165 curr += valid;
166 shortage = count - curr;
167
168 if (!shortage)
169 goto ex;
170
171 /* Before going to the next track, we run through any tail */
172
173 valid = track->tail - track->tailcount;
174 if (valid > count - curr)
175 valid = count - curr;
176
177 if (valid) {
178 track->tailcount += valid;
179 memset(data + curr, 0, valid);
180 }
181 curr += valid;
182 shortage -= valid;
183
184 if (!shortage)
185 goto ex;
186
187 /* ts A61031 - B10103 */
188 if (shortage >= count)
189 track->track_data_done = 1;
190 if (track->end_on_premature_eoi && shortage >= count &&
191 !track->open_ended) {
192 char msg[80];
193 off_t missing, inp_block_size, track_blocks;
194
195 inp_block_size = burn_sector_length(track->mode);
196 track_blocks = burn_track_get_sectors_2(track, 1);
197 missing = track_blocks * inp_block_size - track->sourcecount;
198 sprintf(msg,
199 "Premature end of input encountered. Missing: %.f bytes",
200 (double) missing);
201 libdax_msgs_submit(libdax_messenger, -1, 0x00020180,
202 LIBDAX_MSGS_SEV_FAILURE, LIBDAX_MSGS_PRIO_HIGH,
203 msg, 0,0);
204 /* Memorize that premature end of input happened */
205 track->end_on_premature_eoi = 2;
206 }
207 if (track->open_ended || track->end_on_premature_eoi)
208 goto ex;
209
210 /* If we're still short, and there's a "next" pointer, we pull from that.
211 if that depletes, we'll just fill with 0s.
212 */
213 if (track->source->next) {
214 struct burn_source *src;
215 printf("pulling from next track\n");
216 src = track->source->next;
217 valid = src->read(src, data + curr, shortage);
218 if (valid > 0) {
219 shortage -= valid;
220 curr += valid;
221 }
222 }
223 ex:;
224 /* ts A61024 : general finalizing processing */
225 if(shortage)
226 memset(data + curr, 0, shortage); /* this is old icculus.org */
227 if (track->swap_source_bytes == 1) {
228 for (i = 1; i < count; i += 2) {
229 tr = data[i];
230 data[i] = data[i-1];
231 data[i-1] = tr;
232 }
233 }
234 }
235
236
237 /* ts B20113 : outsourced from get_sector() */
sector_write_buffer(struct burn_drive * d,struct burn_track * track,int flag)238 int sector_write_buffer(struct burn_drive *d,
239 struct burn_track *track, int flag)
240 {
241 int err, i;
242 struct buffer *out;
243
244 out = d->buffer;
245 if (out->sectors <= 0)
246 return 2;
247 err = d->write(d, d->nwa, out);
248 if (err == BE_CANCELLED)
249 return 0;
250
251 /* ts A61101 */
252 if(track != NULL) {
253 track->writecount += out->bytes;
254 track->written_sectors += out->sectors;
255
256 /* Determine current index */
257 for (i = d->progress.index; i + 1 < track->indices; i++) {
258 if (track->index[i + 1] > d->nwa + out->sectors)
259 break;
260 d->progress.index = i + 1;
261 }
262 }
263 /* ts A61119 */
264 d->progress.buffered_bytes += out->bytes;
265
266 d->nwa += out->sectors;
267 out->bytes = 0;
268 out->sectors = 0;
269 return 1;
270 }
271
272
273 /* ts A61009 : seems to hand out sector start pointer in opts->drive->buffer
274 and to count hand outs as well as reserved bytes */
275 /* ts A61101 : added parameter track for counting written bytes */
get_sector(struct burn_write_opts * opts,struct burn_track * track,int inmode)276 static unsigned char *get_sector(struct burn_write_opts *opts,
277 struct burn_track *track, int inmode)
278 {
279 struct burn_drive *d = opts->drive;
280 struct buffer *out = d->buffer;
281 int outmode, seclen, write_ret;
282 unsigned char *ret;
283
284 outmode = get_outmode(opts);
285 if (outmode == 0)
286 outmode = inmode;
287
288 /* ts A61009 : react on eventual failure of burn_sector_length()
289 (should not happen if API tested properly).
290 Ensures out->bytes >= out->sectors */
291 seclen = burn_sector_length(outmode);
292 if (seclen <= 0)
293 return NULL;
294 seclen += burn_subcode_length(outmode);
295
296 /* ts A61219 : opts->obs is eventually a 32k trigger for DVD */
297 /* (there is enough buffer size reserve for track->cdxa_conversion) */
298 if (out->bytes + seclen > BUFFER_SIZE ||
299 (opts->obs > 0 && out->bytes + seclen > opts->obs)) {
300 write_ret = sector_write_buffer(d, track, 0);
301 if (write_ret <= 0)
302 return NULL;
303 }
304 ret = out->data + out->bytes;
305 out->bytes += seclen;
306 out->sectors++;
307
308 return ret;
309 }
310
311 /* ts A61031 */
312 /* Revoke the counting of the most recent sector handed out by get_sector() */
unget_sector(struct burn_write_opts * opts,int inmode)313 static void unget_sector(struct burn_write_opts *opts, int inmode)
314 {
315 struct burn_drive *d = opts->drive;
316 struct buffer *out = d->buffer;
317 int outmode;
318 int seclen;
319
320 outmode = get_outmode(opts);
321 if (outmode == 0)
322 outmode = inmode;
323
324 /* ts A61009 : react on eventual failure of burn_sector_length()
325 (should not happen if API tested properly).
326 Ensures out->bytes >= out->sectors */
327 seclen = burn_sector_length(outmode);
328 if (seclen <= 0)
329 return;
330 seclen += burn_subcode_length(outmode);
331
332 out->bytes -= seclen;
333 out->sectors--;
334 }
335
336
337 /* either inmode == outmode, or outmode == raw. anything else is bad news */
338 /* ts A61010 : changed type to int in order to propagate said bad news */
339 /** @return 1 is ok, <= 0 is failure */
convert_data(struct burn_write_opts * o,struct burn_track * track,int inmode,unsigned char * data)340 static int convert_data(struct burn_write_opts *o, struct burn_track *track,
341 int inmode, unsigned char *data)
342 {
343 int outlen, inlen;
344 int offset = -1;
345 int outmode;
346
347 outmode = get_outmode(o);
348 if (outmode == 0)
349 outmode = inmode;
350
351 outlen = burn_sector_length(outmode);
352 inlen = burn_sector_length(inmode);
353
354 /* ts A61010 */
355 /* a ssert(outlen >= inlen); */
356 if (outlen < inlen || outlen < 0 || inlen < 0)
357 return 0;
358
359 if ((outmode & BURN_MODE_BITS) == (inmode & BURN_MODE_BITS)) {
360 /* see MMC-5 4.2.3.8.5.3 Block Format for Mode 2 form 1 Data
361 Table 24 Mode 2 Formed Sector Sub-header Format */
362 if (track != NULL)
363 if (track->cdxa_conversion == 1)
364 inlen += 8;
365
366 get_bytes(track, inlen, data);
367
368 if (track != NULL)
369 if (track->cdxa_conversion == 1)
370 memmove(data, data + 8, inlen - 8);
371 return 1;
372 }
373
374 /* ts A61010 */
375 /* a ssert(outmode & BURN_MODE_RAW); */
376 if (!(outmode & BURN_MODE_RAW))
377 return 0;
378
379 if (inmode & BURN_MODE1)
380 offset = 16;
381 if (inmode & BURN_MODE_RAW)
382 offset = 0;
383 if (inmode & BURN_AUDIO)
384 offset = 0;
385
386 /* ts A61010 */
387 /* a ssert(offset != -1); */
388 if (offset == -1)
389 return 0;
390
391 get_bytes(track, inlen, data + offset);
392 return 1;
393 }
394
convert_subs(struct burn_write_opts * o,int inmode,unsigned char * subs,unsigned char * sector)395 static void convert_subs(struct burn_write_opts *o, int inmode,
396 unsigned char *subs, unsigned char *sector)
397 {
398 unsigned char *out;
399 int outmode;
400
401 outmode = get_outmode(o);
402 if (outmode == 0)
403 outmode = inmode;
404 sector += burn_sector_length(outmode);
405 /* XXX for sao with subs, we'd need something else... */
406
407 switch (o->block_type) {
408 case BURN_BLOCK_RAW96R:
409 uncook_subs(sector, subs);
410 break;
411
412 case BURN_BLOCK_RAW16:
413 memcpy(sector, subs + 12, 12);
414 out = sector + 12;
415 out[0] = 0;
416 out[1] = 0;
417 out[2] = 0;
418 /*XXX find a better way to deal with partially damaged P channels*/
419 if (subs[2] != 0)
420 out[3] = 0x80;
421 else
422 out[3] = 0;
423 out = sector + 10;
424
425 out[0] = ~out[0];
426 out[1] = ~out[1];
427 break;
428 /* ts A61119 : to silence compiler warnings */
429 default:;
430 }
431 }
432
subcode_toc(struct burn_drive * d,int mode,unsigned char * data)433 static void subcode_toc(struct burn_drive *d, int mode, unsigned char *data)
434 {
435 unsigned char *q;
436 int track;
437 int crc;
438 int min, sec, frame;
439
440 track = d->toc_temp / 3;
441 memset(data, 0, 96);
442 q = data + 12;
443
444 burn_lba_to_msf(d->rlba, &min, &sec, &frame);
445 /*XXX track numbers are BCD
446 a0 - 1st track ctrl
447 a1 - last track ctrl
448 a2 - lout ctrl
449 */
450 q[0] = (d->toc_entry[track].control << 4) + 1;
451 q[1] = 0;
452 if (d->toc_entry[track].point < 100)
453 q[2] = dec_to_bcd(d->toc_entry[track].point);
454 else
455 q[2] = d->toc_entry[track].point;
456 q[3] = dec_to_bcd(min);
457 q[4] = dec_to_bcd(sec);
458 q[5] = dec_to_bcd(frame);
459 q[6] = 0;
460 q[7] = dec_to_bcd(d->toc_entry[track].pmin);
461 q[8] = dec_to_bcd(d->toc_entry[track].psec);
462 q[9] = dec_to_bcd(d->toc_entry[track].pframe);
463
464 #ifdef Libburn_no_crc_C
465 crc = 0; /* dummy */
466 #else
467 crc = crc_ccitt(q, 10);
468 #endif
469
470 q[10] = crc >> 8;
471 q[11] = crc & 0xFF;
472 d->toc_temp++;
473 d->toc_temp %= (d->toc_entries * 3);
474 }
475
sector_toc(struct burn_write_opts * o,int mode)476 int sector_toc(struct burn_write_opts *o, int mode)
477 {
478 struct burn_drive *d = o->drive;
479 unsigned char *data;
480 unsigned char subs[96];
481
482 data = get_sector(o, NULL, mode);
483 if (data == NULL)
484 return 0;
485 /* ts A61010 */
486 if (convert_data(o, NULL, mode, data) <= 0)
487 return 0;
488 subcode_toc(d, mode, subs);
489 convert_subs(o, mode, subs, data);
490 if (sector_headers(o, data, mode, 1) <= 0)
491 return 0;
492 sector_common(++)
493 return 1;
494 }
495
sector_pregap(struct burn_write_opts * o,unsigned char tno,unsigned char control,int mode)496 int sector_pregap(struct burn_write_opts *o,
497 unsigned char tno, unsigned char control, int mode)
498 {
499 struct burn_drive *d = o->drive;
500 unsigned char *data;
501 unsigned char subs[96];
502
503 data = get_sector(o, NULL, mode);
504 if (data == NULL)
505 return 0;
506 /* ts A61010 */
507 if (convert_data(o, NULL, mode, data) <= 0)
508 return 0;
509 subcode_user(o, subs, tno, control, 0, NULL, 1);
510 convert_subs(o, mode, subs, data);
511 if (sector_headers(o, data, mode, 0) <= 0)
512 return 0;
513 sector_common(--)
514 return 1;
515 }
516
sector_postgap(struct burn_write_opts * o,unsigned char tno,unsigned char control,int mode)517 int sector_postgap(struct burn_write_opts *o,
518 unsigned char tno, unsigned char control, int mode)
519 {
520 struct burn_drive *d = o->drive;
521 unsigned char subs[96];
522 unsigned char *data;
523
524 data = get_sector(o, NULL, mode);
525 if (data == NULL)
526 return 0;
527 /* ts A61010 */
528 if (convert_data(o, NULL, mode, data) <= 0)
529 return 0;
530 /* use last index in track */
531 subcode_user(o, subs, tno, control, 1, NULL, 1);
532 convert_subs(o, mode, subs, data);
533 if (sector_headers(o, data, mode, 0) <= 0)
534 return 0;
535 sector_common(++)
536 return 1;
537 }
538
subcode_lout(struct burn_write_opts * o,unsigned char control,unsigned char * data)539 static void subcode_lout(struct burn_write_opts *o, unsigned char control,
540 unsigned char *data)
541 {
542 struct burn_drive *d = o->drive;
543 unsigned char *q;
544 int crc;
545 int rmin, min, rsec, sec, rframe, frame;
546
547 memset(data, 0, 96);
548 q = data + 12;
549
550 burn_lba_to_msf(d->alba, &min, &sec, &frame);
551 burn_lba_to_msf(d->rlba, &rmin, &rsec, &rframe);
552
553 if (((rmin == 0) && (rsec == 0) && (rframe == 0)) ||
554 ((rsec >= 2) && !((rframe / 19) % 2)))
555 memset(data, 0xFF, 12);
556 q[0] = (control << 4) + 1;
557 q[1] = 0xAA;
558 q[2] = 0x01;
559 q[3] = dec_to_bcd(rmin);
560 q[4] = dec_to_bcd(rsec);
561 q[5] = dec_to_bcd(rframe);
562 q[6] = 0;
563 q[7] = dec_to_bcd(min);
564 q[8] = dec_to_bcd(sec);
565 q[9] = dec_to_bcd(frame);
566
567 #ifdef Libburn_no_crc_C
568 crc = 0; /* dummy */
569 #else
570 crc = crc_ccitt(q, 10);
571 #endif
572
573 q[10] = crc >> 8;
574 q[11] = crc & 0xFF;
575 }
576
char_to_isrc(char c)577 static char char_to_isrc(char c)
578 {
579 if (c >= '0' && c <= '9')
580 return c - '0';
581 if (c >= 'A' && c <= 'Z')
582 return 0x11 + (c - 'A');
583 if (c >= 'a' && c <= 'z')
584 return 0x11 + (c - 'a');
585
586 /* ts A61008 : obsoleted by test in burn_track_set_isrc() */
587 /* a ssert(0); */
588 return 0;
589 }
590
subcode_user(struct burn_write_opts * o,unsigned char * subcodes,unsigned char tno,unsigned char control,unsigned char indx,struct isrc * isrc,int psub)591 void subcode_user(struct burn_write_opts *o, unsigned char *subcodes,
592 unsigned char tno, unsigned char control,
593 unsigned char indx, struct isrc *isrc, int psub)
594 {
595 struct burn_drive *d = o->drive;
596 unsigned char *p, *q;
597 int crc;
598 int m, s, f, c, qmode; /* 1, 2 or 3 */
599
600 memset(subcodes, 0, 96);
601
602 p = subcodes;
603 if ((tno == 1) && (d->rlba == -150))
604 memset(p, 0xFF, 12);
605
606 if (psub)
607 memset(p, 0xFF, 12);
608 q = subcodes + 12;
609
610 qmode = 1;
611 /* every 1 in 10 we can do something different */
612 if (d->rlba % 10 == 0) {
613 /* each of these can occur 1 in 100 */
614 if ((d->rlba / 10) % 10 == 0) {
615 if (o->has_mediacatalog)
616 qmode = 2;
617 } else if ((d->rlba / 10) % 10 == 1) {
618 if (isrc && isrc->has_isrc)
619 qmode = 3;
620 }
621 }
622
623 /* ts A61010 : this cannot happen. Assert for fun ? */
624 /* a ssert(qmode == 1 || qmode == 2 || qmode == 3); */
625
626 switch (qmode) {
627 case 1:
628 q[1] = dec_to_bcd(tno); /* track number */
629 q[2] = dec_to_bcd(indx); /* index XXX read this shit
630 from the track array */
631 burn_lba_to_msf(d->rlba, &m, &s, &f);
632 q[3] = dec_to_bcd(m); /* rel min */
633 q[4] = dec_to_bcd(s); /* rel sec */
634 q[5] = dec_to_bcd(f); /* rel frame */
635 q[6] = 0; /* zero */
636 burn_lba_to_msf(d->alba, &m, &s, &f);
637 q[7] = dec_to_bcd(m); /* abs min */
638 q[8] = dec_to_bcd(s); /* abs sec */
639 q[9] = dec_to_bcd(f); /* abs frame */
640 break;
641 case 2:
642 /* media catalog number */
643 q[1] = (o->mediacatalog[0] << 4) + o->mediacatalog[1];
644 q[2] = (o->mediacatalog[2] << 4) + o->mediacatalog[3];
645 q[3] = (o->mediacatalog[4] << 4) + o->mediacatalog[5];
646 q[4] = (o->mediacatalog[6] << 4) + o->mediacatalog[7];
647 q[5] = (o->mediacatalog[8] << 4) + o->mediacatalog[9];
648 q[6] = (o->mediacatalog[10] << 4) + o->mediacatalog[11];
649 q[7] = o->mediacatalog[12] << 4;
650
651 q[8] = 0;
652 burn_lba_to_msf(d->alba, &m, &s, &f);
653 q[9] = dec_to_bcd(f); /* abs frame */
654 break;
655 case 3:
656 c = char_to_isrc(isrc->country[0]);
657 /* top 6 bits of [1] is the first country code */
658 q[1] = c << 2;
659 c = char_to_isrc(isrc->country[1]);
660 /* bottom 2 bits of [1] is part of the second country code */
661 q[1] += (c >> 4);
662 /* top 4 bits if [2] is the rest of the second country code */
663 q[2] = c << 4;
664
665 c = char_to_isrc(isrc->owner[0]);
666 /* bottom 4 bits of [2] is part of the first owner code */
667 q[2] += (c >> 2);
668 /* top 2 bits of [3] is the rest of the first owner code */
669 q[3] = c << 6;
670 c = char_to_isrc(isrc->owner[1]);
671 /* bottom 6 bits of [3] is the entire second owner code */
672 q[3] += c;
673 c = char_to_isrc(isrc->owner[2]);
674 /* top 6 bits of [4] are the third owner code */
675 q[4] = c << 2;
676
677 /* [5] is the year in 2 BCD numbers */
678 q[5] = dec_to_bcd(isrc->year % 100);
679 /* [6] is the first 2 digits in the serial */
680 q[6] = dec_to_bcd(isrc->serial % 100);
681 /* [7] is the next 2 digits in the serial */
682 q[7] = dec_to_bcd((isrc->serial / 100) % 100);
683 /* the top 4 bits of [8] is the last serial digit, the rest is
684 zeros */
685 q[8] = dec_to_bcd((isrc->serial / 10000) % 10) << 4;
686 burn_lba_to_msf(d->alba, &m, &s, &f);
687 q[9] = dec_to_bcd(f); /* abs frame */
688 break;
689 }
690 q[0] = (control << 4) + qmode;
691
692
693 #ifdef Libburn_no_crc_C
694 crc = 0; /* dummy */
695 #else
696 crc = crc_ccitt(q, 10);
697 #endif
698
699 q[10] = crc >> 8;
700 q[11] = crc & 0xff;
701 }
702
sector_lout(struct burn_write_opts * o,unsigned char control,int mode)703 int sector_lout(struct burn_write_opts *o, unsigned char control, int mode)
704 {
705 struct burn_drive *d = o->drive;
706 unsigned char subs[96];
707 unsigned char *data;
708
709 data = get_sector(o, NULL, mode);
710 if (!data)
711 return 0;
712 /* ts A61010 */
713 if (convert_data(o, NULL, mode, data) <= 0)
714 return 0;
715 subcode_lout(o, control, subs);
716 convert_subs(o, mode, subs, data);
717 if (sector_headers(o, data, mode, 0) <= 0)
718 return 0;
719 sector_common(++)
720 return 1;
721 }
722
sector_data(struct burn_write_opts * o,struct burn_track * t,int psub)723 int sector_data(struct burn_write_opts *o, struct burn_track *t, int psub)
724 {
725 struct burn_drive *d = o->drive;
726 unsigned char subs[96];
727 unsigned char *data;
728
729 data = get_sector(o, t, t->mode);
730 if (data == NULL)
731 return 0;
732 /* ts A61010 */
733 if (convert_data(o, t, t->mode, data) <= 0)
734 return 0;
735
736 /* ts A61031 */
737 if ((t->open_ended || t->end_on_premature_eoi) && t->track_data_done) {
738 unget_sector(o, t->mode);
739 return 2;
740 }
741
742 /* ts A61219 : allow track without .entry */
743 if (t->entry == NULL)
744 ;
745 else if (!t->source->read_sub)
746 subcode_user(o, subs, t->entry->point,
747 t->entry->control, 1, &t->isrc, psub);
748 else if (!t->source->read_sub(t->source, subs, 96))
749 subcode_user(o, subs, t->entry->point,
750 t->entry->control, 1, &t->isrc, psub);
751 convert_subs(o, t->mode, subs, data);
752
753 if (sector_headers(o, data, t->mode, 0) <= 0)
754 return 0;
755 sector_common(++)
756 return 1;
757 }
758
burn_msf_to_lba(int m,int s,int f)759 int burn_msf_to_lba(int m, int s, int f)
760 {
761 if (m < 90)
762 return (m * 60 + s) * 75 + f - 150;
763 else
764 return (m * 60 + s) * 75 + f - 450150;
765 }
766
burn_lba_to_msf(int lba,int * m,int * s,int * f)767 void burn_lba_to_msf(int lba, int *m, int *s, int *f)
768 {
769 if (lba >= -150) {
770 *m = (lba + 150) / (60 * 75);
771 *s = (lba + 150 - *m * 60 * 75) / 75;
772 *f = lba + 150 - *m * 60 * 75 - *s * 75;
773 } else {
774 *m = (lba + 450150) / (60 * 75);
775 *s = (lba + 450150 - *m * 60 * 75) / 75;
776 *f = lba + 450150 - *m * 60 * 75 - *s * 75;
777 }
778 }
779
dec_to_bcd(int d)780 int dec_to_bcd(int d)
781 {
782 int top, bottom;
783
784 top = d / 10;
785 bottom = d - (top * 10);
786 return (top << 4) + bottom;
787 }
788
sector_headers_is_ok(struct burn_write_opts * o,int mode)789 int sector_headers_is_ok(struct burn_write_opts *o, int mode)
790 {
791 if (mode & BURN_AUDIO) /* no headers for "audio" */
792 return 1;
793 if (o->write_type == BURN_WRITE_SAO)
794 return 1;
795
796 /* ts A61031 */
797 if (o->write_type == BURN_WRITE_TAO)
798 return 1;
799
800 if (mode & BURN_MODE1)
801 return 2;
802 return 0;
803 }
804
805 /* ts A90830 : changed return type to int
806 @return 0= failure
807 1= success
808 */
sector_headers(struct burn_write_opts * o,unsigned char * out,int mode,int leadin)809 int sector_headers(struct burn_write_opts *o, unsigned char *out,
810 int mode, int leadin)
811 {
812
813 #ifdef Libburn_ecma130ab_includeD
814
815 struct burn_drive *d = o->drive;
816 unsigned int crc;
817 int min, sec, frame;
818 int modebyte = -1;
819 int ret;
820
821 ret = sector_headers_is_ok(o, mode);
822 if (ret != 2)
823 return !!ret;
824 modebyte = 1;
825
826 out[0] = 0;
827 memset(out + 1, 0xFF, 10); /* sync */
828 out[11] = 0;
829
830 if (leadin) {
831 burn_lba_to_msf(d->rlba, &min, &sec, &frame);
832 out[12] = dec_to_bcd(min) + 0xA0;
833 out[13] = dec_to_bcd(sec);
834 out[14] = dec_to_bcd(frame);
835 out[15] = modebyte;
836 } else {
837 burn_lba_to_msf(d->alba, &min, &sec, &frame);
838 out[12] = dec_to_bcd(min);
839 out[13] = dec_to_bcd(sec);
840 out[14] = dec_to_bcd(frame);
841 out[15] = modebyte;
842 }
843 if (mode & BURN_MODE1) {
844
845 #ifdef Libburn_no_crc_C
846 crc = 0; /* dummy */
847 #else
848 crc = crc_32(out, 2064);
849 #endif
850
851 out[2064] = crc & 0xFF;
852 crc >>= 8;
853 out[2065] = crc & 0xFF;
854 crc >>= 8;
855 out[2066] = crc & 0xFF;
856 crc >>= 8;
857 out[2067] = crc & 0xFF;
858 }
859 if (mode & BURN_MODE1) {
860 memset(out + 2068, 0, 8);
861 burn_rspc_parity_p(out);
862 burn_rspc_parity_q(out);
863 }
864 burn_ecma130_scramble(out);
865 return 1;
866
867 #else /* Libburn_ecma130ab_includeD */
868
869 int ret;
870
871 ret = sector_headers_is_ok(o, mode);
872 if (ret != 2)
873 return (!! ret);
874
875 /* ts A90830 : lec.c is copied from cdrdao.
876 I have no idea yet how lec.c implements the Reed-Solomon encoding
877 which is described in ECMA-130 for CD-ROM.
878 So this got removed for now.
879 */
880 libdax_msgs_submit(libdax_messenger, o->drive->global_index,
881 0x0002010a,
882 LIBDAX_MSGS_SEV_FATAL, LIBDAX_MSGS_PRIO_HIGH,
883 "Raw CD write modes are not supported", 0, 0);
884 return 0;
885
886 #endif /* ! Libburn_ecma130ab_includeD */
887
888 }
889
890 #if 0
891 void process_q(struct burn_drive *d, unsigned char *q)
892 {
893 unsigned char i[5];
894 int mode;
895
896 mode = q[0] & 0xF;
897 /* burn_print(12, "mode: %d : ", mode);*/
898 switch (mode) {
899 case 1:
900 /* burn_print(12, "tno = %d : ", q[1]);
901 burn_print(12, "index = %d\n", q[2]);
902 */
903 /* q[1] is the track number (starting at 1) q[2] is the index
904 number (starting at 0) */
905 #warning this is totally bogus
906 if (q[1] - 1 > 99)
907 break;
908 if (q[2] > d->toc->track[q[1] - 1].indices) {
909 burn_print(12, "new index at %d\n", d->alba);
910 d->toc->track[q[1] - 1].index[q[2]] = d->alba;
911 d->toc->track[q[1] - 1].indices++;
912 }
913 break;
914 case 2:
915 /* XXX do not ignore these */
916 break;
917 case 3:
918 /* burn_print(12, "ISRC data in mode 3 q\n");*/
919 i[0] = isrc[(q[1] << 2) >> 2];
920 /* burn_print(12, "0x%x 0x%x 0x%x 0x%x 0x%x\n", q[1], q[2], q[3], q[4], q[5]);
921 burn_print(12, "ISRC - %c%c%c%c%c\n", i[0], i[1], i[2], i[3], i[4]);
922 */
923 break;
924 default:
925
926 /* ts A61009 : if reactivated then without Assert */
927 a ssert(0);
928 }
929 }
930 #endif
931
932 /* this needs more info. subs in the data? control/adr? */
933
934 /* ts A61119 : One should not use unofficial compiler extensions.
935 >>> Some day this function needs to be implemented. At least for now
936 the result does not match the "mode" of cdrecord -toc.
937 */
938 /*
939 #warning sector_identify needs to be written
940 */
sector_identify(unsigned char * data)941 int sector_identify(unsigned char *data)
942 {
943
944 /*
945 burn_ecma130_scramble(data);
946 check mode byte for 1 or 2
947 test parity to see if it's a valid sector
948 if invalid, return BURN_MODE_AUDIO;
949 else return mode byte (what about mode 2 formless? heh)
950 */
951
952 return BURN_MODE1;
953 }
954