2 Copyright (c) 2005-2006, John Hurst
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
8 1. Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14 derived from this software without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include <hex_utils.h>
36 // This is how much we read when we're reading from a file and we don't know
37 // how long the packet is. This gives us the K (16 bytes) and L (4-9 bytes)
38 // and the remaining bytes for an even read (tmp_read_size % 16 == 0)
39 const ui32_t kl_length = ASDCP::SMPTE_UL_LENGTH + ASDCP::MXF_BER_LENGTH;
40 const ui32_t tmp_read_size = 32;
42 //------------------------------------------------------------------------------------------
47 ASDCP::KLVPacket::InitFromBuffer(const byte_t* buf, ui32_t buf_len, const byte_t* label)
49 Result_t result = KLVPacket::InitFromBuffer(buf, buf_len);
51 if ( ASDCP_SUCCESS(result) )
52 result = ( memcmp(m_KeyStart, label, SMPTE_UL_LENGTH) == 0 ) ?
53 RESULT_OK : RESULT_FAIL;
60 ASDCP::KLVPacket::InitFromBuffer(const byte_t* buf, ui32_t buf_len)
62 m_KeyStart = m_ValueStart = 0;
63 m_KLLength = m_ValueLength = 0;
65 if ( memcmp(buf, SMPTE_UL_START, 4) != 0 )
67 DefaultLogSink().Error("Unexpected UL preamble: %02x.%02x.%02x.%02x\n",
68 buf[0], buf[1], buf[2], buf[3]);
73 if ( ! read_BER(buf + SMPTE_UL_LENGTH, &tmp_size) )
76 m_ValueLength = tmp_size;
77 m_KLLength = SMPTE_UL_LENGTH + BER_length(buf + SMPTE_UL_LENGTH);
79 m_ValueStart = buf + m_KLLength;
85 ASDCP::KLVPacket::HasUL(const byte_t* ul)
87 if ( m_KeyStart == 0 )
90 return ( memcmp(ul, m_KeyStart, SMPTE_UL_LENGTH) == 0 ) ? true : false;
95 ASDCP::KLVPacket::WriteKLToBuffer(ASDCP::FrameBuffer& Buffer, const byte_t* label, ui32_t length)
97 if ( Buffer.Size() + kl_length > Buffer.Capacity() )
99 DefaultLogSink().Error("Small write buffer\n");
103 memcpy(Buffer.Data() + Buffer.Size(), label, SMPTE_UL_LENGTH);
105 if ( ! write_BER(Buffer.Data() + Buffer.Size() + SMPTE_UL_LENGTH, length, MXF_BER_LENGTH) )
108 Buffer.Size(Buffer.Size() + kl_length);
114 ASDCP::KLVPacket::Dump(FILE* stream, bool show_hex)
119 if ( m_KeyStart != 0 )
121 assert(m_ValueStart);
123 for ( ui32_t i = 0; i < SMPTE_UL_LENGTH; i++ )
124 fprintf(stream, "%02x.", m_KeyStart[i]);
126 const MDDEntry* Entry = GetMDDEntry(m_KeyStart);
127 fprintf(stream, "\b len: %7lu (%s)\n", m_ValueLength, (Entry ? Entry->name : "Unknown"));
129 if ( show_hex && m_ValueLength < 1000 )
130 hexdump(m_ValueStart, ASDCP::xmin(m_ValueLength, (ui32_t)64), stream);
134 fprintf(stream, "*** Malformed packet ***\n");
140 ASDCP::KLVFilePacket::InitFromFile(const FileReader& Reader, const byte_t* label)
142 Result_t result = KLVFilePacket::InitFromFile(Reader);
144 if ( ASDCP_SUCCESS(result) )
145 result = ( memcmp(m_KeyStart, label, SMPTE_UL_LENGTH) == 0 ) ?
146 RESULT_OK : RESULT_FAIL;
153 ASDCP::KLVFilePacket::InitFromFile(const FileReader& Reader)
156 byte_t tmp_data[tmp_read_size];
158 m_KeyStart = m_ValueStart = 0;
159 m_KLLength = m_ValueLength = 0;
162 Result_t result = Reader.Read(tmp_data, tmp_read_size, &read_count);
164 if ( ASDCP_FAILURE(result) )
167 if ( read_count < (SMPTE_UL_LENGTH + 1) )
169 DefaultLogSink().Error("Short read of Key and Length got %lu\n", read_count);
170 return RESULT_READFAIL;
173 if ( memcmp(tmp_data, SMPTE_UL_START, 4) != 0 )
175 DefaultLogSink().Error("Unexpected UL preamble: %02x.%02x.%02x.%02x\n",
176 tmp_data[0], tmp_data[1], tmp_data[2], tmp_data[3]);
180 if ( ! read_BER(tmp_data + SMPTE_UL_LENGTH, &tmp_size) )
182 DefaultLogSink().Error("BER Length decoding error\n");
186 if ( tmp_size > MAX_KLV_PACKET_LENGTH )
188 char intbuf[IntBufferLen];
189 DefaultLogSink().Error("Packet length %s exceeds internal limit\n",
190 ui64sz(tmp_size, intbuf));
194 ui32_t remainder = 0;
195 ui32_t ber_len = BER_length(tmp_data + SMPTE_UL_LENGTH);
196 m_KLLength = SMPTE_UL_LENGTH + ber_len;
197 m_ValueLength = tmp_size;
198 ui32_t packet_length = m_ValueLength + m_KLLength;
200 result = m_Buffer.Capacity(packet_length);
202 if ( ASDCP_FAILURE(result) )
205 m_KeyStart = m_Buffer.Data();
206 m_ValueStart = m_Buffer.Data() + m_KLLength;
207 m_Buffer.Size(packet_length);
209 // is the whole packet in the tmp buf?
210 if ( packet_length <= tmp_read_size )
212 assert(packet_length <= read_count);
213 memcpy(m_Buffer.Data(), tmp_data, packet_length);
215 if ( (remainder = read_count - packet_length) != 0 )
217 DefaultLogSink().Warn("Repositioning pointer for short packet\n");
218 ASDCP::fpos_t pos = Reader.Tell();
219 assert(pos > remainder);
220 result = Reader.Seek(pos - remainder);
225 if ( read_count < tmp_read_size )
227 DefaultLogSink().Error("Short read of packet body, expecting %lu, got %lu\n",
228 m_Buffer.Size(), read_count);
229 return RESULT_READFAIL;
232 memcpy(m_Buffer.Data(), tmp_data, tmp_read_size);
233 remainder = m_Buffer.Size() - tmp_read_size;
237 result = Reader.Read(m_Buffer.Data() + tmp_read_size, remainder, &read_count);
239 if ( read_count != remainder )
241 DefaultLogSink().Error("Short read of packet body, expecting %lu, got %lu\n",
242 remainder+tmp_read_size, read_count+tmp_read_size);
243 result = RESULT_READFAIL;
253 ASDCP::KLVFilePacket::WriteKLToFile(FileWriter& Writer, const byte_t* label, ui32_t length)
255 byte_t buffer[kl_length];
256 memcpy(buffer, label, SMPTE_UL_LENGTH);
258 if ( ! write_BER(buffer+SMPTE_UL_LENGTH, length, MXF_BER_LENGTH) )
262 Writer.Write(buffer, kl_length, &write_count);
263 assert(write_count == kl_length);