/****************************************************************************** * Copyright (c) 2000-2023 Ericsson Telecom AB * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html * * Contributors: * Gabor Szalai - initial implementation and initial documentation * Peter Kremer * Sandor Palugyai * Tibor Harai ******************************************************************************/ // // File: RTP_File.cc // Description: Media files operation for RTP // Rev: R5B // Prodnr: CNL 113 392 // #include "RTP_File_Types.hh" #include #include #include #define CREAT_MODE 0644 namespace RTP__File__Types{ enum Operation {READ, WRITE}; typedef struct{ CHARSTRING *filename; int fd; int block_size; struct stat stat_buf; } File_info_type; void log_info_list(); int f_Fileinfo_Check(const int& fd, const Operation& OPERATION); int f_Operation_Check(const int& fd, const int& blockno, const int& nof_b, const Operation& OPERATION, const int& hdr_off); void f__Count__JPEG__Header__Offset(RTP__FileInfo& fi); File_info_type *file_info_list = NULL; int nof_file_infos = 0; INTEGER f__INIT__CODEC(const CHARSTRING& filename, const INTEGER& block_size, const InitOperType& INIT_TYPE) { if(filename=="") TTCN_error("INIT__CODEC: empty filename is not allowed"); if((int)block_size<=0) TTCN_error("INIT__CODEC: Block size must be a positive integer"); if( !(file_info_list = (File_info_type*) realloc( file_info_list, (nof_file_infos+1)*sizeof(File_info_type) )) ) TTCN_error("INIT__CODEC: There is not enough memory."); switch (INIT_TYPE) { case InitOperType::OPEN: if( (file_info_list[nof_file_infos].fd = open((const char *)filename, O_RDONLY))<0 ) TTCN_error("INIT__CODEC: Cannot open file '%s'\n", (const char *)filename); break; case InitOperType::CREATE: if( (file_info_list[nof_file_infos].fd = creat((const char *)filename, CREAT_MODE))<0 ) TTCN_error("INIT__CODEC: Cannot create file '%s'\n", (const char *)filename); break; default: TTCN_error("INIT__CODEC: Wrong init_type setting! Available: OPEN, CREATE.\n"); break; } file_info_list[nof_file_infos].filename = new CHARSTRING(filename); file_info_list[nof_file_infos].block_size = (int)block_size; if( stat((const char *)*file_info_list[nof_file_infos].filename, &file_info_list[nof_file_infos].stat_buf) == -1 ) TTCN_error("INIT__CODEC: Cannot gather file info"); if( file_info_list[nof_file_infos].stat_buf.st_size%block_size != 0 ) TTCN_warning("INIT__CODEC: File %s contains uncomplete blocks", (const char *)filename); TTCN_Logger::log(TTCN_DEBUG,"INIT__CODEC: filename: %s, origfilename: %s\n", (const char *)*file_info_list[nof_file_infos].filename, (const char*)filename); nof_file_infos++; log_info_list(); return INTEGER(file_info_list[nof_file_infos-1].fd); } OCTETSTRING f__GET__CONTENT(const INTEGER& fd, const INTEGER& blockno, const INTEGER& nof_blocks_to_read, const INTEGER& header_offset) { int bytes_to_read = f_Operation_Check((int)fd, (int)blockno, (int)nof_blocks_to_read, READ, (int)header_offset); if (!bytes_to_read) return OCTETSTRING(0, NULL); unsigned char * buf = (unsigned char*) malloc(bytes_to_read); if(!buf) TTCN_error("GET_CONTENT: There is not enough memory."); int read_data = 0; if((read_data = read(fd, buf, bytes_to_read))<0) TTCN_error("GET_CONTENT: unsuccesful read (%d)", read_data); OCTETSTRING retval(read_data, buf); free(buf); return retval; } void f__Count__JPEG__Header__Offset(RTP__FileInfo& fi) { int i = f_Fileinfo_Check((int)fi.fd(), READ); struct stat &stat_buf = file_info_list[i].stat_buf; int hdr_off = (int)fi.headerOffset(); if(hdr_off < 0) TTCN_error("Get_Media_Header: Header offset must be a non-negative integer!"); if(stat_buf.st_size < hdr_off) TTCN_error("Get_Media_Header: Size of file %s is smaller than the size of header!", (const char *)*file_info_list[i].filename); if(lseek((int)fi.fd(), 0, SEEK_SET) < 0) TTCN_error("Count_JPEG_Header_Offset: Cannot set the starting position in file %s\n", (const char *)*file_info_list[i].filename); unsigned char * buf = (unsigned char*) malloc(hdr_off); if(!buf) TTCN_error("Count_JPEG_Header_Offset: There is not enough memory."); int read_data = 0; if((read_data = read((int)fi.fd(), buf, hdr_off))<0) TTCN_error("Count_JPEG_Header_Offset: unsuccesful read (%d)",read_data); fi.headerOffset() = hdr_off + ((((int)buf[hdr_off-2]) << 8) | buf[hdr_off-1]); free(buf); } INTEGER f__PUT__CONTENT(const INTEGER& fd, const INTEGER& blockno, const OCTETSTRING& stream, const INTEGER& header_offset) { int bytes_to_write = f_Operation_Check((int)fd, (int)blockno, stream.lengthof(), WRITE, (int)header_offset); if (!bytes_to_write) return 0; unsigned char * buf = (unsigned char*)(const unsigned char*) stream; if (write(fd, buf, bytes_to_write) != bytes_to_write) TTCN_error("PUT_CONTENT: unsuccesful write to file"); return bytes_to_write; } void f__CLOSE__CODEC(const INTEGER& fd) { for(int i=0;i