diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index b5007b9..c643da4 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2013.12.12.140531" +#define Cdrskin_timestamP "2014.01.07.115938" diff --git a/libburn/drive.c b/libburn/drive.c index e116097..c7218b8 100644 --- a/libburn/drive.c +++ b/libburn/drive.c @@ -80,6 +80,7 @@ int burn_setup_drive(struct burn_drive *d, char *fname) d->do_stream_recording = 0; d->stream_recording_start= 0; d->role_5_nwa = 0; + d->features = NULL; return 1; } @@ -104,6 +105,7 @@ void burn_drive_free_subs(struct burn_drive *d) if (d->stdio_fd >= 0) close (d->stdio_fd); d->stdio_fd = -1; + burn_feature_descr_free(&(d->features), 0); sg_dispose_drive(d, 0); } @@ -3430,3 +3432,70 @@ int burn_drive_was_feat21_failure(struct burn_drive *d) } +/* ts B40106 */ +int burn_feature_descr_new(struct burn_feature_descr **new, + unsigned char *descr, int descr_len, int flag) +{ + struct burn_feature_descr *o; + + *new = NULL; + if (descr_len < 4) + return 0; + (*new) = o = calloc(1, sizeof(struct burn_speed_descriptor)); + if (o == NULL) + return -1; + o->feature_code = (descr[0] << 8) | descr[1]; + o->flags = descr[2]; + if (descr[3] > descr_len - 4) + o->data_lenght = 0; + else + o->data_lenght = descr[3]; + o->data = NULL; + o->next = NULL; + if (o->data_lenght > 0) { + o->data = calloc(1, o->data_lenght); + if (o->data == NULL) { + burn_feature_descr_free(new, 0); + return -1; + } + memcpy(o->data, descr + 4, o->data_lenght); + } + return 1; +} + + +/* ts B40106 */ +int burn_feature_descr_free(struct burn_feature_descr **descr, int flag) +{ + struct burn_feature_descr *o, *next; + + if (*descr == NULL) + return 0; + for (o = *descr; o != NULL; o = next) { + next = o->next; + if (o->data != NULL) + free(o->data); + free((char *) o); + } + *descr = NULL; + return 1; +} + + +/* ts B40107 */ +int burn_drive_has_feature(struct burn_drive *d, int feature_code, + struct burn_feature_descr **descr, int flag) +{ + struct burn_feature_descr *o; + + for (o = d->features; o != NULL; o = o->next) { + if (o->feature_code == feature_code) { + if (descr != NULL) + *descr = o; + return 1; + } + } + return 0; +} + + diff --git a/libburn/drive.h b/libburn/drive.h index fa6674f..3f975a0 100644 --- a/libburn/drive.h +++ b/libburn/drive.h @@ -1,7 +1,7 @@ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens - Copyright (c) 2006 - 2011 Thomas Schmitt + Copyright (c) 2006 - 2014 Thomas Schmitt Provided under GPL version 2 or later. */ @@ -19,6 +19,7 @@ struct command; struct mempage; struct scsi_mode_data; struct burn_speed_descriptor; +struct burn_feature_descr; #define LEAD_IN 1 #define GAP 2 @@ -155,4 +156,16 @@ int burn_abort_5(int patience, /* Send a default mode page 05 to CD and DVD-R-oids */ int burn_drive_send_default_page_05(struct burn_drive *d, int flag); + +/* ts B40106 */ +int burn_feature_descr_new(struct burn_feature_descr **new, + unsigned char *descr, int descr_len, int flag); + +/* ts B40106 */ +int burn_feature_descr_free(struct burn_feature_descr **new, int flag); + +/* ts B40107 */ +int burn_drive_has_feature(struct burn_drive *d, int feature_code, + struct burn_feature_descr **descr, int flag); + #endif /* __DRIVE */ diff --git a/libburn/mmc.c b/libburn/mmc.c index f96b39e..e59ab8a 100644 --- a/libburn/mmc.c +++ b/libburn/mmc.c @@ -2928,6 +2928,7 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len) struct command *c = NULL; int phys_if_std = 0; char *phys_name = ""; + struct burn_feature_descr *recent_feature = NULL, *new_feature; /* Enable this to get loud and repeated reports about the feature set : # define Libburn_print_feature_descriptorS 1 @@ -2949,6 +2950,8 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len) d->current_is_supported_profile = 0; d->current_is_guessed_profile = 0; d->num_profiles = 0; + if (d->features != NULL) + burn_feature_descr_free(&(d->features), 0); d->current_has_feat21h = 0; d->current_feat21h_link_size = -1; d->current_feat23h_byte4 = 0; @@ -3080,6 +3083,17 @@ static int mmc_get_configuration_al(struct burn_drive *d, int *alloc_len) descr_len = 4 + descr[3]; feature_code = (descr[0] << 8) | descr[1]; feature_is_current = descr[2] & 1; + + ret = burn_feature_descr_new(&new_feature, descr, + up_to - descr, 0); + if (ret > 0) { + if (d->features == NULL) + d->features = new_feature; + else + recent_feature->next = new_feature; + recent_feature = new_feature; + } + if (only_current && !feature_is_current) continue; diff --git a/libburn/transport.h b/libburn/transport.h index a98f5c0..8bbd702 100644 --- a/libburn/transport.h +++ b/libburn/transport.h @@ -1,7 +1,7 @@ /* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */ /* Copyright (c) 2004 - 2006 Derek Foreman, Ben Jansens - Copyright (c) 2006 - 2013 Thomas Schmitt + Copyright (c) 2006 - 2014 Thomas Schmitt Provided under GPL version 2 or later. */ @@ -131,6 +131,24 @@ struct burn_format_descr { }; +/* ts B40106 : represents a Feature Descriptor as of mmc5r03c.pdf 5.2.2 + There can be many of them. Thus a linked list. +*/ +struct burn_feature_descr { + unsigned short feature_code; + + unsigned char flags; /* bit0= current + bit1= persistent + bit2-5= version + */ + + unsigned char data_lenght; + unsigned char *data; + + struct burn_feature_descr *next; +}; + + /** Gets initialized in enumerate_common() and burn_drive_register() */ struct burn_drive { @@ -182,6 +200,9 @@ struct burn_drive unsigned char all_profiles[256]; int num_profiles; + /* ts B40106 : All feature descriptors as read from drive */ + struct burn_feature_descr *features; + /* ts A70128 : MMC-to-MMC feature info from 46h for DVD-RW. Quite internal. Regard as opaque :) */