General

Decode data from alldata.kwi file in Volvo MMM+ DVD

This is the PERL script you may use to get some data about the DVD maps you have.

This is in reference to Reverse engineering Volvo RTI MMM+ DVD maps

#!/usr/bin/perl

my $kiwi = {
	"All Data Management Frame" => {
		1 => { offset => 0, length => 2048, item_name => "Data Volume" },
		2 =>  { offset => 2048, length => 2048, item_name => "A sequence of Management Table Headers [n]", classification => "b" },
	},
	"Data Volume" => {
		1 => { offset => 0, length => 64, item_name => "System-specific Identification", remark => "This field identifies the maker of the system if the data is system-dependent", classification => "a" },
		2 => { offset => 64, length => 64, item_name => "Data author Identification", remark => "This field describes the maker who created the media data", classification => "a" },
		3 => { offset => 128, length => 32, item_name => "System Identification", remark => "The first 12 bytes of the system identification describe MID of the hardware manufacturer. The definition of data after MID depends on the maker who identifies the system", classification => "a" },
		4 => { offset => 160, length => 64, data_type => "C", item_name => "Format Version Number", remark => "The format version number is FORMAT_VERSION_KIWIaa-bb-cc, where the underscore (_) means a space character. 
		When the specification is revised, a new version number aa-bb-cc is assigned according to the rules below: 
			aa: Increased when the specification is amended significantly. This number change makes the existing application program partially or entirely unavailable. 
			bb: Increased when the specification is amended to remove any inconvenience or when data is added to the specification to enhance the function. This number change does not affect the performance of existing application programs (the compatibility remains). 
			cc: Increased when typographical errors are corrected or when description is changed or added. This number change does not affect the performance of application programs (the compatibility remains). 
		To align the data length to 32 words, the remaining blanks are padded with 0(16)/one word. 
		The character types of the data to be stored are: 
			aa: Number (decimal number from 01 to 99) 
			bb: Number (decimal number from 00 to 99) 
			cc: Number (decimal number from 00 to 99)",
		classification => "a" },
		5 => { offset => 224, length => 64, item_name => "Data Version Number", remark => "Two different data version numbers are assigned; one for a prototype and the other for mass-production.
		(a) Mass Production 
		 The data version number DATA_VERSION_aa/bb/cc/dd is assigned, where the underscore (_) is a space 
		 character. This number is unique on a production lot basis. This number must be changed when editing the data will change the address on the media, such as the case where data source is updated or the media are newly edited. 
		 	aa: The year when the product is manufactured (ex. 97) 
		 	bb: The month when the product is manufactured (ex. 03) 
		 	cc: The day when the product is manufactured (ex. 10) 
		 	dd: Serial number assigned to products manufactured in a day (ex. 01) 
		  To align the data length to 32 words, the remaining blanks are padded with 0(16) for one word. 
	 		The character types of the data to be stored are: 
			 aa: Number (decimal number from 00 to 99) 
			 bb: Number (decimal number from 01 to 12) 
			 cc: Number (decimal number from 01 to 31) 
			 dd: Number (decimal number from 01 to 99) 
		(b) Prototype 
		 The data version number DATA_VERSION_aa-bbbbb is assigned, where the underscore (_) is a space character. This number is unique on an the lot of each manufacturers basis. This number must be changed when the situation described in (a) occurs. 
			aa: Media code 
			bbbbb: Serial number 
		  To align the data length to 32 words, the remaining blanks are padded with 0(16)/one word. 
			The character types of the data to be stored are: 
			aa: Alphabet 
			bbbbb: Number (decimal number from 00001 to 99999)",
	 	 classification => "b" },
		6 => { offset => 288, length => 128, data_type => "CC", item_name => "Disk Title", classification => "a" },
		7 => { offset => 416, length => 8, data_type => "B", item_name => "Data Contents", classification => "a" },
		8 => { offset => 424, length => 32, data_type => "C", item_name => "Media Version Number", remark => "The media version number is Vaa.bb.cc. This is a unique number assigned to each medium which stores map data. 
		When the specification is revised, a new version number aa.bb.cc is assigned according to the rules below: 
			aa: Increased when the application program or the map data are amended significantly. The system checks the version number conformability. 
			bb: Increased when a minor change is applied to the application program or the map data. The system checks the version number conformability 
			cc: Increased when minor problems in the application program or the map data are cleared or when maintenance is made. This number change does not affect the performance of application programs (especially the implementation function). The system does not check the version number conformability. 
		To align the data length to 16 words, the remaining blanks are padded with 0(16)/one word. 
		The character types of the data to be stored are: 
			aa: Number (decimal number from 00 to 99) 
			bb: Number (decimal number from 00 to 99) 
			cc: Number (decimal number from 00 to 99) 
		If the wild code (*) is used, the system check can be evaded. 
		Note:  In Japan, a different method might be used.",
		 classification => "b" },
		9 => { offset => 456, length => 16, item_name => "Data Coverage", classification => "a" },
		10 => { offset => 472, length => 2, data_type => "N", item_name => "Logical Sector Size", classification => "a" },
		11 => { offset => 474, length => 2, data_type => "N", item_name => "Sector Size", classification => "a" },
		12 => { offset => 476, length => 2, data_type => "B:B", item_name => "Background Data Default Information", classification => "a" },
		13 => { offset => 478, length => 14, item_name => "RESERVED", classification => "a" },
		14 => { offset => 492, length => 256, item_name => "Level Management Information", classification => "a" },
		15 => { offset => 748, length => 1300, item_name => "RESERVED", classification => "a" },
	},
	"System-specific Identification" => {
		1 => { offset => 0, length => 12, data_type => "MID", item_name => 'Maker Identification' },
		2 => { offset => 12, length => 52, data_type => "C", item_name => "System-specific identification defined by the maker" },
	},
	"Data Author Identification" => {
		1 => { offset => 0, length => 12, data_type => "MID", item_name => "Maker Identification" },
		2 => { offset => 12, length => 52, data_type => "C", item_name => "Identification of the Data Author (defined by the author)" },
	},
	"Data Contents" => {
		"Word 0" => {
			1 => { bit => 15, description => "Main Map", remarks => "International Common Data" },
			2 => { bit => 14, description => "Route Planning", remarks => "International Common Data" },
			3 => { bit => 13, description => "Index Data", remarks => "International Common Data" },
			4 => { bit => "11:0", description => "RESERVED", remarks => "International Common Data" },
		},
		"Word 1" => {
			1 => { bit => "15:0", description => "RESERVED", remarks => "Country/Region common data" },
		},
		"Word 2" => {
			2 => { bit => "15:0", description => "RESERVED", remarks => "Common to group companies" },
		},
		"Word 3" => {
			3 => { bit => "15:0", description => "RESERVED", remarks => "System dependent" },
		},
	},
};

sub DecodeKiwiFrame {
	my($name) = shift(@_);
	my($frame) = shift(@_);

	print "DecodeKiwiFrame($name)\n";

	if(exists($kiwi->{$name})) {
		print "\nName: $name\n";
		foreach $no (sort { $a <=> $b } (keys(%{$kiwi->{$name}}))) {
			print " Number: $no\n";
			if(exists($kiwi->{$name}->{$no}->{remark})) {
				print "  Remark:\n";
				print $kiwi->{$name}->{$no}->{remark}."\n";
			}
			if(!exists($kiwi->{$name}->{$no}->{data_type})) {
				print "  No data type. Recurse.\n";
				if(exists($kiwi->{$name}->{$no}->{offset})) {
					print "  Offset: ".$kiwi->{$name}->{$no}->{offset}."\n";
					if(exists($kiwi->{$name}->{$no}->{length})) {
						print "  Length: ".$kiwi->{$name}->{$no}->{length}."\n";
						&DecodeKiwiFrame($kiwi->{$name}->{$no}->{item_name},
								 substr($frame,
								 	$kiwi->{$name}->{$no}->{offset},
									$kiwi->{$name}->{$no}->{length})
						);
					}
				}
			} else {
				if(exists($kiwi->{$name}->{$no}->{offset})) {
					print "  Offset: ".$kiwi->{$name}->{$no}->{offset}."\n";
					if(exists($kiwi->{$name}->{$no}->{length})) {
						print "  Length: ".$kiwi->{$name}->{$no}->{length}."\n";
						my($field);
						if( $kiwi->{$name}->{$no}->{data_type} eq "C" ||
				    		    $kiwi->{$name}->{$no}->{data_type} eq "CC" ||
				    		    $kiwi->{$name}->{$no}->{data_type} eq "MID" ) {
							print "  Character substring.\n";
							$field=substr($frame,
								$kiwi->{$name}->{$no}->{offset},
								$kiwi->{$name}->{$no}->{length}
								);
						}
						if( $kiwi->{$name}->{$no}->{data_type} eq "N" ) {
							print "   Unsigned short unpack.\n";
							$field=unpack("s",
								      substr($frame,
									$kiwi->{$name}->{$no}->{offset},
									$kiwi->{$name}->{$no}->{length}
								      )
								);
						}
						if($field) {
							print "   Data Type: ".$kiwi->{$name}->{$no}->{data_type}."\n";
							print "   Item Name: ".$kiwi->{$name}->{$no}->{item_name}."\n";
							print "   Item Value: $field\n";
						}
					}		
				}
			}
		}
	}
}

if(open(ALLDATA,"<ALLDATA.KWI")) {
 my $buffer;

 binmode(ALLDATA); 

 if(read(ALLDATA,$buffer,4096)) {
 	&DecodeKiwiFrame("All Data Management Frame",$buffer);
 }

 close(ALLDATA);
}

Leave a Reply

Your email address will not be published. Required fields are marked *