Commit 01b565e2 authored by Andrey Filippov's avatar Andrey Filippov

edited for EO, restored write camogm.disk to /dev/sda1

parent a7ffbc6d
...@@ -618,27 +618,27 @@ int sendImageFrame(camogm_state *state) ...@@ -618,27 +618,27 @@ int sendImageFrame(camogm_state *state)
// D3(fprintf (debug_file,"sendImageFrame: format=%d, set_format=%d\n", state->format, state->set_format)); // D3(fprintf (debug_file,"sendImageFrame: format=%d, set_format=%d\n", state->format, state->set_format));
if (state->format != state->set_format) { if (state->format != state->set_format) {
D2(fprintf(debug_file, "sendImageFrame:2: state->format(0x%x) != state->set_format(0x%x)\n", state->format, state->set_format)); D1(fprintf(debug_file, "sendImageFrame:2: state->format(0x%x) != state->set_format(0x%x)\n", state->format, state->set_format));
return -CAMOGM_FRAME_CHANGED; return -CAMOGM_FRAME_CHANGED;
} }
// check if file size is exceeded (assuming fopen),-CAMOGM_FRAME_CHANGED will trigger a new segment // check if file size is exceeded (assuming fopen),-CAMOGM_FRAME_CHANGED will trigger a new segment
if (!state->rawdev_op && (state->vf) && (state->segment_length >= 0) && (ftell(state->vf) > state->segment_length)) { if (!state->rawdev_op && (state->vf) && (state->segment_length >= 0) && (ftell(state->vf) > state->segment_length)) {
D2(fprintf(debug_file, "sendImageFrame:3: segment length exceeded\n")); D1(fprintf(debug_file, "sendImageFrame:3: segment length exceeded\n"));
return -CAMOGM_FRAME_NEXTFILE; return -CAMOGM_FRAME_NEXTFILE;
} }
//same for open //same for open
if (!state->rawdev_op && ((state->ivf) >= 0) && (state->segment_length >= 0) && (lseek(state->ivf, 0, SEEK_CUR) > state->segment_length)) { if (!state->rawdev_op && ((state->ivf) >= 0) && (state->segment_length >= 0) && (lseek(state->ivf, 0, SEEK_CUR) > state->segment_length)) {
D3(fprintf(debug_file, "sendImageFrame:4: segment length exceeded\n")); D1(fprintf(debug_file, "sendImageFrame:4: segment length exceeded\n"));
return -CAMOGM_FRAME_NEXTFILE; return -CAMOGM_FRAME_NEXTFILE;
} }
// check the frame pointer is valid // check the frame pointer is valid
if ((fp = lseek(state->fd_circ[port], state->cirbuf_rp[port], SEEK_SET)) < 0) { if ((fp = lseek(state->fd_circ[port], state->cirbuf_rp[port], SEEK_SET)) < 0) {
D2(fprintf(debug_file, "sendImageFrame:5: invalid frame\n")); D1(fprintf(debug_file, "sendImageFrame:5: invalid frame\n"));
return -CAMOGM_FRAME_INVALID; //it will probably be that allready return -CAMOGM_FRAME_INVALID; //it will probably be that allready
} }
// is the frame ready? // is the frame ready?
if (lseek(state->fd_circ[port], LSEEK_CIRC_READY, SEEK_END) < 0) { if (lseek(state->fd_circ[port], LSEEK_CIRC_READY, SEEK_END) < 0) {
D3(fprintf(debug_file, "?6")) ; //frame not ready, frame pointer seems valid, but not ready D1(fprintf(debug_file, "?6")) ; //frame not ready, frame pointer seems valid, but not ready
D6(fprintf(debug_file, ",FRAME NOT READY fp=0x%x\n", fp)); //frame not ready, frame pointer seems valid, but not ready D6(fprintf(debug_file, ",FRAME NOT READY fp=0x%x\n", fp)); //frame not ready, frame pointer seems valid, but not ready
return -CAMOGM_FRAME_NOT_READY; // frame pointer valid, but no frames yet return -CAMOGM_FRAME_NOT_READY; // frame pointer valid, but no frames yet
} }
...@@ -658,7 +658,7 @@ int sendImageFrame(camogm_state *state) ...@@ -658,7 +658,7 @@ int sendImageFrame(camogm_state *state)
//optionally save it to global read pointer (i.e. for debugging with imgsrv "/pointers") //optionally save it to global read pointer (i.e. for debugging with imgsrv "/pointers")
if (state->save_gp) lseek(state->fd_circ[port], LSEEK_CIRC_SETP, SEEK_END); if (state->save_gp) lseek(state->fd_circ[port], LSEEK_CIRC_SETP, SEEK_END);
state->frames_skip_left[port]--; state->frames_skip_left[port]--;
D2(fprintf(debug_file, "?7\n")); //frame not ready D1(fprintf(debug_file, "?7\n")); //frame not ready
return -CAMOGM_FRAME_NOT_READY; // the required frame is not ready return -CAMOGM_FRAME_NOT_READY; // the required frame is not ready
} }
...@@ -689,6 +689,8 @@ int sendImageFrame(camogm_state *state) ...@@ -689,6 +689,8 @@ int sendImageFrame(camogm_state *state)
if (timestamp_start >= state->circ_buff_size[port]) timestamp_start -= state->circ_buff_size[port]; if (timestamp_start >= state->circ_buff_size[port]) timestamp_start -= state->circ_buff_size[port];
D4(fprintf(debug_file, "_3_")); D4(fprintf(debug_file, "_3_"));
memcpy(&(state->this_frame_params[port].timestamp_sec), (unsigned long* )&ccam_dma_buf[state->port_num][timestamp_start >> 2], 8); memcpy(&(state->this_frame_params[port].timestamp_sec), (unsigned long* )&ccam_dma_buf[state->port_num][timestamp_start >> 2], 8);
D1(fprintf(debug_file, "%ld.%06ld ",state->this_frame_params[port].timestamp_sec,state->this_frame_params[port].timestamp_usec); \
if (debug_level < 2) fprintf(debug_file,"\n"););
// verify that the essential current frame params did not change, if they did - return an error (need new file header) // verify that the essential current frame params did not change, if they did - return an error (need new file header)
if (!state->ignore_fps && ((state->frame_params[port].width != state->this_frame_params[port].width) || if (!state->ignore_fps && ((state->frame_params[port].width != state->this_frame_params[port].width) ||
(state->frame_params[port].height != state->this_frame_params[port].height))) { (state->frame_params[port].height != state->this_frame_params[port].height))) {
...@@ -2211,13 +2213,15 @@ unsigned int select_port(camogm_state *state) ...@@ -2211,13 +2213,15 @@ unsigned int select_port(camogm_state *state)
#ifdef MIN_USED_SIZE #ifdef MIN_USED_SIZE
D1(if ((chn >=0) && (lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END) >= 0) && \ D1(if ((chn >=0) && (lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END) >= 0) && \
(lseek(state->fd_circ[chn], LSEEK_CIRC_USED, SEEK_END) >= MIN_USED_SIZE)) {\ (lseek(state->fd_circ[chn], LSEEK_CIRC_USED, SEEK_END) >= MIN_USED_SIZE)) {\
fprintf(debug_file, "sel port: %i, min free = %08ld, MANY=%d EMPTY=%d BUSY=%d [%d%d%d%d%d%d%d%d] @ %07d ", \ fprintf(debug_file, "sel port: %i, min free=%08ld, MANY=%d EMPTY=%d BUSY=%d [%d%d%d%d%d%d%d%d] @ %07d ", \
chn, min_sz, \ chn, min_sz, \
state->writer_params.circbuf_many, get_num_empty(&state->writer_params), get_num_busy(&state->writer_params), \ state->writer_params.circbuf_many, get_num_empty(&state->writer_params), get_num_busy(&state->writer_params), \
params->chunk_page_state[0],params->chunk_page_state[1],params->chunk_page_state[2],params->chunk_page_state[3], \ params->chunk_page_state[0],params->chunk_page_state[1],params->chunk_page_state[2],params->chunk_page_state[3], \
params->chunk_page_state[4],params->chunk_page_state[5],params->chunk_page_state[6],params->chunk_page_state[7], \ params->chunk_page_state[4],params->chunk_page_state[5],params->chunk_page_state[6],params->chunk_page_state[7], \
get_fpga_usec(state->fd_fparmsall[0], 0)); if (debug_level < 2) fprintf(debug_file,"\n");}\ get_fpga_usec(state->fd_fparmsall[0], 0));}\
else if (debug_level >= 6) fprintf(debug_file,"no port is ready @ %07d\n", get_fpga_usec(state->fd_fparmsall[0], 0))); else if (debug_level >= 6) fprintf(debug_file,"no port is ready @ %07d\n", get_fpga_usec(state->fd_fparmsall[0], 0)));
//if (debug_level < 2) fprintf(debug_file,"\n");}
#else #else
D1(if ((chn >=0) && (lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END) >= 0)) {\ D1(if ((chn >=0) && (lseek(state->fd_circ[chn], LSEEK_CIRC_READY, SEEK_END) >= 0)) {\
......
...@@ -679,7 +679,8 @@ void *jpeg_writer(void *thread_args) ...@@ -679,7 +679,8 @@ void *jpeg_writer(void *thread_args)
{ {
int dbg_start_wait = 0, dbg_wait, dbg_time; int dbg_start_wait = 0, dbg_wait, dbg_time;
char * dbg_pref; char * dbg_pref;
struct iovec write_segments[SEGMENTS_NUMBER];// 3 #define MAX_SEGM_NUMBER 16 // temporary, debugging
struct iovec write_segments[MAX_SEGM_NUMBER]; // SEGMENTS_NUMBER];// 3
int num_write_segments, seg_len; int num_write_segments, seg_len;
int dbg_us1=0, dbg_us2=0, dbg_us; // save usec for difference int dbg_us1=0, dbg_us2=0, dbg_us; // save usec for difference
pthread_t this_thread = pthread_self(); pthread_t this_thread = pthread_self();
...@@ -688,10 +689,12 @@ void *jpeg_writer(void *thread_args) ...@@ -688,10 +689,12 @@ void *jpeg_writer(void *thread_args)
int reset_rem; int reset_rem;
long long dbg_pos64; long long dbg_pos64;
int i, i0, i1, wpage; int i, i0, i1, wpage;
char * bufp;
// int32_t res32; // int32_t res32;
// int64_t res64; // int64_t res64;
// int errno32, errno64; // int errno32, errno64;
ssize_t iovlen, l, ll, l0, l1, blocks_write; // , wpage; ssize_t iovlen, image_len_padded, ll, l0, l1, blocks_write; // , wpage;
ssize_t writev_wlen; ssize_t writev_wlen;
struct iovec split_chunk; struct iovec split_chunk;
int blockdev_fd; ///< file descriptor for open block device where frame will be recorded, local for the thread int blockdev_fd; ///< file descriptor for open block device where frame will be recorded, local for the thread
...@@ -808,26 +811,45 @@ void *jpeg_writer(void *thread_args) ...@@ -808,26 +811,45 @@ void *jpeg_writer(void *thread_args)
if (wpage >= 0) { if (wpage >= 0) {
D6(fprintf(debug_file, "%s_w01_: got write segment page %d (preparing %d) @ %07d\n", dbg_pref,\ D6(fprintf(debug_file, "%s_w01_: got write segment page %d (preparing %d) @ %07d\n", dbg_pref,\
wpage, params->chunk_page_prep, get_fpga_usec(state->fd_fparmsall[0], 0))); wpage, params->chunk_page_prep, get_fpga_usec(state->fd_fparmsall[0], 0)));
l = 0; image_len_padded = 0;
reset_rem = 0; reset_rem = 0;
params->last_ret_val = 0; params->last_ret_val = 0;
// inputs from params->data_chunks, returns number of result chunks // inputs from params->data_chunks, returns number of result chunks
#define MAX_SEGM_PAGES 0xa0
#define MAX_SEGM_LENGTH (MAX_SEGM_PAGES * PAGE_PHYS) // 0xa0000 // multiple of
// Seems that I introduced a bug into kernel - it can not handle too longsegments
num_write_segments = 0; num_write_segments = 0;
for (i = 0; i < SEGMENTS_NUMBER; i++){ for (i = 0; i < SEGMENTS_NUMBER; i++){
seg_len = params->data_segments[wpage][i].iov_len; seg_len = params->data_segments[wpage][i].iov_len;
image_len_padded+=seg_len;
if (seg_len > 0){ if (seg_len > 0){
if (seg_len <= MAX_SEGM_LENGTH) {
write_segments[num_write_segments++] = params->data_segments[wpage][i]; write_segments[num_write_segments++] = params->data_segments[wpage][i];
l+=seg_len; } else {
bufp = (char *) params->data_segments[wpage][i].iov_base;
while (seg_len >= MAX_SEGM_LENGTH){
write_segments[num_write_segments ].iov_base = bufp;
write_segments[num_write_segments++].iov_len = MAX_SEGM_LENGTH;
bufp += MAX_SEGM_LENGTH;
seg_len -= MAX_SEGM_LENGTH;
}
if (seg_len > 0){
write_segments[num_write_segments ].iov_base = bufp;
write_segments[num_write_segments++].iov_len = seg_len;
}
}
} }
} }
// l is correct here
// chunk_index = get_data_buffers(state, chunks_iovec[wpage], FILE_CHUNKS_NUM, wpage); // chunk_index = get_data_buffers(state, chunks_iovec[wpage], FILE_CHUNKS_NUM, wpage);
// assuming write is block-aligned // assuming write is block-aligned
if (num_write_segments > 0) { if (num_write_segments > 0) {
// Moved rollover here // Moved rollover here
blocks_write = l / PHY_BLOCK_SIZE; // here LBA, 512 blocks_write = image_len_padded / PHY_BLOCK_SIZE; // here LBA, 512
if (get_lba_next(params) + blocks_write <= params->lba_end) { // almost always - single write if (get_lba_next(params) + blocks_write <= params->lba_end) { // almost always - single write
D2(dbg_us1=get_fpga_usec(state->fd_fparmsall[0], 0)); D2(dbg_us1=get_fpga_usec(state->fd_fparmsall[0], 0));
D2(dbg_pos = lseek64(blockdev_fd, 0, SEEK_CUR); if (dbg_pos < 0) fprintf( \ D3(dbg_pos = lseek64(blockdev_fd, 0, SEEK_CUR); if (dbg_pos < 0) fprintf( \
debug_file,"%slseek64()->-1, errno=%d(%s)", dbg_pref,errno, strerror(errno))); debug_file,"%slseek64()->-1, errno=%d(%s)", dbg_pref,errno, strerror(errno)));
D6(fprintf(debug_file, "%s_w02_: starting emul_writev@ %07d\n", dbg_pref, dbg_us1)); D6(fprintf(debug_file, "%s_w02_: starting emul_writev@ %07d\n", dbg_pref, dbg_us1));
...@@ -882,7 +904,7 @@ void *jpeg_writer(void *thread_args) ...@@ -882,7 +904,7 @@ void *jpeg_writer(void *thread_args)
writev_wlen = write (blockdev_fd, write_segments[i].iov_base, write_segments[i].iov_len); writev_wlen = write (blockdev_fd, write_segments[i].iov_base, write_segments[i].iov_len);
// if (i == 1) { // only for segment 1, if other write thread also is writing second (large) segment // if (i == 1) { // only for segment 1, if other write thread also is writing second (large) segment
D2(fprintf(debug_file, \ D3(fprintf(debug_file, \
"%s_w02x_: i=%d start =0x%08x, len=0x%08x\n", dbg_pref, i, (int)write_segments[i].iov_base, (int)write_segments[i].iov_len)); "%s_w02x_: i=%d start =0x%08x, len=0x%08x\n", dbg_pref, i, (int)write_segments[i].iov_base, (int)write_segments[i].iov_len));
// } // }
if (writev_wlen < 0) { if (writev_wlen < 0) {
...@@ -906,19 +928,19 @@ void *jpeg_writer(void *thread_args) ...@@ -906,19 +928,19 @@ void *jpeg_writer(void *thread_args)
D4(syslog (LOG_INFO, "%s_w03_: finished emul_writev, pos= %lld, len = %d(0x%x) thread ID = %ld @ %07d (+ %07d, +%07d)", dbg_pref,\ D4(syslog (LOG_INFO, "%s_w03_: finished emul_writev, pos= %lld, len = %d(0x%x) thread ID = %ld @ %07d (+ %07d, +%07d)", dbg_pref,\
dbg_pos, iovlen, iovlen, pthread_self(), dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2))); dbg_pos, iovlen, iovlen, pthread_self(), dbg_us, (dbg_us-dbg_us1), (dbg_us-dbg_us2)));
D2(dbg_us2=dbg_us); D2(dbg_us2=dbg_us);
if (iovlen < l) { if (iovlen < image_len_padded) {
D0(fprintf(debug_file, "%semul_writev error: %s (returned %i, expected %i)\n", dbg_pref, strerror(errno), iovlen, l)); D0(fprintf(debug_file, "%semul_writev error: %s (returned %i, expected %i)\n", dbg_pref, strerror(errno), iovlen, image_len_padded));
params->last_ret_val = -CAMOGM_FRAME_FILE_ERR; params->last_ret_val = -CAMOGM_FRAME_FILE_ERR;
reset_rem = 1; reset_rem = 1;
} else { } else {
// update statistic // update statistic
state->rawdev.last_jpeg_size = l; // state->rawdev.last_jpeg_size = l;
state->rawdev.total_rec_len += state->rawdev.last_jpeg_size; // state->rawdev.total_rec_len += state->rawdev.last_jpeg_size;
D6(fprintf(debug_file, "%sCurrent position in block device: %lld\n", dbg_pref, lseek64(blockdev_fd, 0, SEEK_CUR))); D6(fprintf(debug_file, "%sCurrent position in block device: %lld\n", dbg_pref, lseek64(blockdev_fd, 0, SEEK_CUR)));
} }
} else { // Split into two writes: to the end of partition and startion from the beginning } else { // Split into two writes: to the end of partition and startion from the beginning
l0 = get_lba_next(params) * PHY_BLOCK_SIZE; // remaining to be written before rollover l0 = get_lba_next(params) * PHY_BLOCK_SIZE; // remaining to be written before rollover
l1 = l - l0; // remaining to be written after rollover l1 = image_len_padded - l0; // remaining to be written after rollover
i1 = 0; // start of the second write i1 = 0; // start of the second write
if (l0 > 0) { // should be always if (l0 > 0) { // should be always
ll = 0; ll = 0;
...@@ -975,10 +997,10 @@ void *jpeg_writer(void *thread_args) ...@@ -975,10 +997,10 @@ void *jpeg_writer(void *thread_args)
params->last_ret_val = -CAMOGM_FRAME_FILE_ERR; params->last_ret_val = -CAMOGM_FRAME_FILE_ERR;
reset_rem = 1; reset_rem = 1;
} else { } else {
// update statistic (for both parts of the split write) /// // update statistic (for both parts of the split write)
state->rawdev.last_jpeg_size = l; /// state->rawdev.last_jpeg_size = l;
state->rawdev.total_rec_len += state->rawdev.last_jpeg_size; /// state->rawdev.total_rec_len += state->rawdev.last_jpeg_size;
D6(fprintf(debug_file, "%s(1 of 2) Current position in block device: %lld\n", dbg_pref, lseek64(blockdev_fd, 0, SEEK_CUR))); D6(fprintf(debug_file, "%s(2 of 2) Current position in block device: %lld\n", dbg_pref, lseek64(blockdev_fd, 0, SEEK_CUR)));
} }
} }
} }
...@@ -1000,6 +1022,12 @@ void *jpeg_writer(void *thread_args) ...@@ -1000,6 +1022,12 @@ void *jpeg_writer(void *thread_args)
reset_segments(state, reset_rem, wpage); reset_segments(state, reset_rem, wpage);
pthread_mutex_lock(&params->writer_mutex); pthread_mutex_lock(&params->writer_mutex);
params->chunk_page_state[wpage] = SEGPAGE_EMPTY; params->chunk_page_state[wpage] = SEGPAGE_EMPTY;
// update statistics right here !
state->rawdev.last_jpeg_size = image_len_padded;
state->rawdev.total_rec_len += state->rawdev.last_jpeg_size;
D3(fprintf(debug_file, "%sl=%d, total_rec_len=%lld\n",dbg_pref, image_len_padded, state->rawdev.total_rec_len));
// D6(fprintf(debug_file, "%sCurrent position in block device: %lld\n", dbg_pref, lseek64(blockdev_fd, 0, SEEK_CUR)));
// moved to while waiting // moved to while waiting
// pthread_cond_signal(&params->main_cond); // signal to main thread that prepares data // pthread_cond_signal(&params->main_cond); // signal to main thread that prepares data
pthread_cond_broadcast(&params->writer_cond); // signal to other writer thread waiting for this one to finish writing pthread_cond_broadcast(&params->writer_cond); // signal to other writer thread waiting for this one to finish writing
......
<?
/*!***************************************************************************
*! FILE NAME : camogmgui.php
*! DESCRIPTION: command interface for the camogm recorder and camogm GUI
*! Copyright (C) 2008 Elphel, Inc
*! -----------------------------------------------------------------------------**
*!
*! This program is free software: you can redistribute it and/or modify
*! it under the terms of the GNU General Public License as published by
*! the Free Software Foundation, either version 3 of the License, or
*! (at your option) any later version.
*!
*! This program is distributed in the hope that it will be useful,
*! but WITHOUT ANY WARRANTY; without even the implied warranty of
*! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*! GNU General Public License for more details.
*!
*! You should have received a copy of the GNU General Public License
*! along with this program. If not, see <http://www.gnu.org/licenses/>.
*! -----------------------------------------------------------------------------**
*! $Log: camogm_interface.php,v $
*! Revision 1.23 2013/05/28 01:49:19 dzhimiev
*! 1. fixed list-command
*!
*! Revision 1.22 2013/05/26 04:41:32 dzhimiev
*! 1. minor changes to avoid php hanging when not communicating with camogm
*!
*! Revision 1.21 2012/04/14 01:25:12 dzhimiev
*! 1. added 'list' - shows files at the specified path
*!
*! Revision 1.20 2011/06/02 12:29:07 oneartplease
*! added new option to set_start_after_timestamp to allow setting record start time in the future without first having to read current camera time "p5" as parameter will start recording at camera time "p"lus 5 seconds
*!
*! Revision 1.19 2011/04/04 20:19:36 dzhimiev
*! 1. added frame skipping option
*!
*! Revision 1.18 2011/01/01 13:04:47 oneartplease
*! added commands to set frameskipping and secondsskipping (timelapse)
*!
*! Revision 1.17 2010/08/20 20:16:55 oneartplease
*! cleaned up setcookie commands
*!
*! Revision 1.16 2010/08/08 20:19:46 dzhimiev
*! 1. added write/read elphel parameters
*! 2. camogm: debuglev , start_after_timestamp
*!
*! Revision 1.15 2010/06/24 17:31:55 dzhimiev
*! 1. added camogm process run check (ps | grep camogm)
*!
*! Revision 1.14 2010/01/19 10:07:20 oneartplease
*! added unmounting command
*!
*! Revision 1.12 2009/10/13 12:42:31 oneartplease
*! moved save_gp=1 command
*!
*! Revision 1.11 2009/06/24 15:20:04 oneartplease
*! file renaming works with absolute paths now as preparation for mounting multiple devices
*!
*! Revision 1.5 2009/03/26 12:20:40 oneartplease
*! audio and geotagging updates, both are not fully working yet though
*!
*! Revision 1.9 2009/01/14 08:26:19 oneartplease
*! minor updates
*!
*!
*! Revision 1.0 2008/09/21 Sebastian Pichelhofer
*! start and stop commands for ajax execution
*!
*/
define('SSD_ROOT', '/mnt/sda1/');
define('ASSUME_EXT4', 'sda1'); // comment out after testing
//define('USE_SYSLOG', 1);
$cmd = $_GET['cmd'];
$debug = $_GET['debug'];
$debuglev = $_GET['debuglev'];
$cmd_pipe = "/var/state/camogm_cmd";
$cmd_state = "/var/state/camogm.state";
$cmd_port = "3456";
//$default_state = "/home/root/camogm.disk";
$default_state = "/etc/elphel393/camogm.disk";
//$state_file = "/mnt/sda1/camogm.disk";
$state_file = "/etc/elphel393/camogm.disk";
$start_str = "camogm -n " . $cmd_pipe . " -p " . $cmd_port;
//if (defined('USE_SYSLOG')) {
if (USE_SYSLOG > 0) {
syslog(LOG_NOTICE, "camogm_interface.php:");
foreach ($_GET as $k => $v){
syslog(LOG_NOTICE, $k ." -> ".$v);
}
}
function check_camogm_running(){
global $start_str;
$camogm_running = false;
exec('ps | grep "camogm"', $arr);
$check = implode("<br/>",$arr);
if (strstr($check, $start_str)){
$camogm_running = true;
}
return $camogm_running;
}
if ($cmd == "run_camogm")
{
// allow CORS: needed for multi cams unified control
header('Access-Control-Allow-Origin: *');
if (isset($_GET['state_file'])){
$state_file = $_GET['state_file'];
}
if(!check_camogm_running()) {
echo "camogm is not running, starting\n";
$start_str = $start_str . " -s " . $state_file;
// clean
exec("rm " . $cmd_pipe);
exec("rm " . $cmd_state);
if (!$debug) exec($start_str.' > /dev/null 2>&1 &'); // "> /dev/null 2>&1 &" makes sure it is really really run as a background job that does not wait for input
else exec($start_str.$debug.' > dev/null 2>&1 &');
for($i=0;$i<5;$i++) {
if (file_exists($cmd_pipe))
break;
sleep(1);
}
if ($debug) {
$fcmd = fopen($cmd_pipe, "w");
fprintf($fcmd,"debuglev=$debuglev");
fclose($fcmd);
}
// set fast recording mode if there is at least one suitable partition or revert to legacy 'mov' mode
if (USE_SYSLOG > 0) syslog(LOG_NOTICE, "before get_raw_dev()");
$partitions = get_raw_dev();
if (USE_SYSLOG > 0) syslog(LOG_NOTICE, "after get_raw_dev()");
if (!empty($partitions)) {
reset($partitions);
$cmd_str = 'format=jpeg;' . 'rawdev_path=' . key($partitions) . ';';
write_cmd_pipe($cmd_str);
} else {
$cmd_str = 'format=mov;save_gp=1;';
write_cmd_pipe($cmd_str);
}
}else{
echo "camogm is running\n";
}
}
else if (($cmd == "status") || ($cmd == "state"))
{
if (check_camogm_running()) $camogm_running = "on";
else $camogm_running = "off";
if ($camogm_running=="on"){
$pipe="/var/state/camogm.state";
$mode=0777;
if(!file_exists($pipe)) {
umask(0);
posix_mkfifo($pipe,$mode);
}
$fcmd=fopen($cmd_pipe,"w");
fprintf($fcmd, "xstatus=%s\n",$pipe);
fclose($fcmd);
$status=file_get_contents($pipe);
if ($cmd == "state") {
$start = strpos($status, "<state>") + 7;
$len = strpos($status, "</state>", $start) - $start ; // including ""
$state = substr($status, $start, $len);
$status = "<?xml version='1.0'?><camogm_state>\n<state>".$state."</state>\n</camogm_state>";
}
}else{
$status = "<?xml version='1.0'?><camogm_state>\n<state>".$camogm_running."</state>\n</camogm_state>";
}
header("Content-Type: text/xml");
header("Content-Length: ".strlen($status)."\n");
header("Pragma: no-cache\n");
// allow CORS: needed for multi cams unified control
header('Access-Control-Allow-Origin: *');
printf("%s", $status);
}
else if ($cmd == "run_status")
{
if (check_camogm_running()) $camogm_running = "on";
else $camogm_running = "off";
$status="<?xml version='1.0'?><camogm_state>\n<state>".$camogm_running."</state>\n</camogm_state>";
header("Content-Type: text/xml");
header("Content-Length: ".strlen($status)."\n");
header("Pragma: no-cache\n");
// allow CORS: needed for multi cams unified control
header('Access-Control-Allow-Origin: *');
printf("%s", $status);
}
else if ($cmd=="get_hdd_space"){
if (isset($_GET['mountpoint']))
$mountpoint = $_GET['mountpoint'];
if (!$mountpoint){
$mountpoint = '/mnt/sda1';
}
else
$mountpoint = '/mnt/sda1';
// make sure something is mounted on mountpoint
exec('mount', $arr);
$mounted = implode("", $arr);
if ((strstr($mounted, $mountpoint)) && (is_dir($mountpoint))) $res = disk_free_space($mountpoint);
else $res = 0;
xml_header();
echo "<command>".$cmd."</command>";
echo "<".$cmd.">";
echo $res;
echo "</".$cmd.">";
xml_footer();
}
else if ($cmd=="mount") { // mount media like HDD
if (isset($_GET['partition']))
$partition = $_GET['partition'];
else
$partition = '/dev/sda1';
//$partition = '/dev/hda1';
if (isset($_GET['mountpoint']))
$mountpoint = $_GET['mountpoint'];
else
$mountpoint = '/mnt/sda1';
exec('mkdir '.$mountpoint);
//exec('mkdir /mnt/sda1');
exec('mount '.$partition." ".$mountpoint);
//exec('mount /dev/hda1 /mnt/sda1');
xml_header();
echo "<command>".$cmd."</command>";
echo "<".$cmd.">";
echo "done";
echo "</".$cmd.">";
xml_footer();
}
else if (($cmd=="umount") || ($cmd=="unmount")) { // unmount media like HDD
$message = "";
if (isset($_GET['mountpoint'])) {
$mountpoint = $_GET['mountpoint'];
exec('umount '.$mountpoint);
$message = "done";
} else {
$message = "missing argument: mountpoint";
}
xml_header();
echo "<command>".$cmd."</command>";
echo "<".$cmd.">";
echo $message;
echo "</".$cmd.">";
xml_footer();
}
else if ($cmd=="set_quality") {
$quality = $_GET['quality'];
$sensor_port = $_GET['sensor_port'];
$thisFrameNumber=elphel_get_frame($sensor_port);
elphel_set_P_value($sensor_port,ELPHEL_QUALITY,$quality+0,$thisFrameNumber+3);
//$thisFrameNumber=elphel_get_frame();
//elphel_wait_frame_abs($thisFrameNumber+3);
xml_header();
echo "<command>".$cmd."</command>";
echo "<".$cmd.">";
echo elphel_get_P_value($sensor_port,ELPHEL_QUALITY);
echo "</".$cmd.">";
xml_footer();
}
else if ($cmd=="get_quality") {
$sensor_port = $_GET['sensor_port'];
xml_header();
echo "<command>".$cmd."</command>";
echo "<".$cmd.">";
echo elphel_get_P_value($sensor_port,ELPHEL_QUALITY);
echo "</".$cmd.">";
xml_footer();
}
else if ($cmd=="set_parameter") {
$pname = $_GET['pname'];
$pvalue = $_GET['pvalue'];
$sensor_port = $_GET['sensor_port'];
//elphel_skip_frames($sensor_port,1);
$thisFrameNumber=elphel_get_frame($sensor_port);
if (isset($_GET['pframe'])) {
$pframe = intval($_GET['pframe']);
} else {
$pframe = 3;
}
$constant=constant("ELPHEL_$pname");
elphel_set_P_value($sensor_port,$constant,$pvalue+0,$thisFrameNumber+$pframe);
xml_header();
echo "<command>".$cmd."</command>";
echo "<".$cmd.">";
echo elphel_get_P_value($sensor_port,$constant);
echo "</".$cmd.">";
xml_footer();
}
else if ($cmd=="get_parameter") {
$pname = $_GET['pname'];
$sensor_port = $_GET['sensor_port'];
$constant=constant("ELPHEL_$pname");
xml_header();
echo "<command>".$cmd."</command>";
echo "<".$cmd.">";
echo elphel_get_P_value($sensor_port,$constant);
echo "</".$cmd.">";
xml_footer();
}
else if ($cmd=="set_skip") {
$skipping_mask = $_GET['skip_mask'];
//!!!sub!!!
//exec("fpcf -w 4d $skipping_mask");
xml_header();
echo "<command>".$cmd."</command>";
echo "<".$cmd.">";
echo "done";
echo "</".$cmd.">";
xml_footer();
}
else if ($cmd=="list") {
unset ($message);
if (isset($_GET['path'])) $path = $_GET['path'];
else {
$message = "the path is not set";
}
if (!isset($message)) {
if (is_dir($path)) {
$files = scandir($path);
foreach ($files as $file){
if (is_file("$path/$file")) $message .= "<f>$path/$file</f>\n";
}
}else{
$message = "directory not found";
}
}
xml_header();
echo "<command>".$cmd."</command>";
echo "<".$cmd.">";
echo $message;
echo "</".$cmd.">";
xml_footer();
}
else if ($cmd=="list_raw_devices"){
$devices = get_raw_dev();
xml_header();
echo "<command>".$cmd."</command>";
echo "<".$cmd.">";
foreach ($devices as $device => $size) {
echo "<item>";
echo "<raw_device>" . $device . "</raw_device>";
echo "<size>" . round($size / 1048576, 2) . "</size>";
echo "</item>";
}
echo "</".$cmd.">";
xml_footer();
}
else if ($cmd=="list_partitions"){
xml_header();
$partitions = get_partitions();
foreach ($partitions as $device=>$size) {
echo "<item>";
echo " <device>" . $device . "</device>";
echo " <size>" . round($size / 1048576, 2) . "</size>";
echo "</item>";
}
xml_footer();
}
else
{
$fcmd = fopen($cmd_pipe, "w");
switch ($cmd) { // cookies have to be set before any output
case "set_prefix":
$prefix = $_GET['prefix'];
setcookie("directory", $prefix);
break;
}
xml_header();
echo "<command>".$cmd."</command>";
echo "<".$cmd.">";
switch ($cmd)
{
case "start":
// Camogm starts with all ports disabled
fprintf($fcmd, "port_enable=0;port_enable=1;port_enable=2;port_enable=3;");
fprintf($fcmd,"start;\n");
break;
case "stop":
fprintf($fcmd,"stop;\n");
exec('sync');
break;
case "exit":
fprintf($fcmd,"exit;\n");
exec('sync');
break;
case "file_rename":
// Now requires full path (like "/mnt/sda1/test1.mov") for file_old
// and either a full path or just a filename for file_new
if ((!isset($_GET['file_old'])) || (!isset($_GET['file_new']))) {
echo "wrong arguments";
break;
}
$old_name = $_GET['file_old'];
$new_name = $_GET['file_new'];
if (!strrpos($new_name, "/")) {
$new_name = substr($old_name, 0, strrpos($old_name, "/")+1).$new_name;
}
if ($old_name == $new_name) {
echo "filenames match";
break;
}
if (file_exists($new_name)) {
echo "file_new already exists";
break;
}
if (!file_exists($old_name)) {
echo "file_old does not exist";
break;
}
// no errors found, so do the rename
if (rename($old_name, $new_name))
echo "done";
else
echo "undefined error";
break;
case "listdevices":
exec ("cat /proc/partitions", $arr1);
exec ("cat /proc/mounts", $arr2);
$ret = get_mnt_dev();
$mnt_dev = $ret["devices"];
$j = 0;
// first two lines are header and empty line separator, skip them
$i = 2;
while($i < count($arr1)) {
// skip flash and RAM disk partitions
if (!strpos($arr1[$i], "mtdblock") && !strpos($arr1[$i], "ram")) {
$temp = $arr1[$i];
while(strstr($temp, " ")) {
$temp = str_replace(chr(9), " ", $temp);
$temp = str_replace(" ", " ", $temp);
}
if (preg_match_all('/ +[a-z]{3,3}[0-9]{1,1}$/', $temp, $available_partitons) > 0) {
// remove leading spaces
$partitions[$j] = preg_replace("/^ +/", "", $available_partitons[0][0]);
$parts = explode(" ", $temp);
$size[$j] = $parts[3];
$j++;
}
}
$i++;
}
$j = 0;
foreach ($partitions as $partition) {
$include = false;
foreach ($mnt_dev as $dev) {
if (strpos($dev, $partition))
$include = true;
}
if ($include) {
echo "<item>";
echo "<partition>/dev/".$partition."</partition>";
echo "<size>".round($size[$j]/1024/1024, 2) ." GB</size>";
$j++;
$i = 0;
while($i < count($arr2)) {
if(strpos($arr2[$i], $partition))
{
$parts = explode(" ", $arr2[$i]);
$mountpoint = $parts[1];
$filesystem = $parts[2];
}
$i++;
}
if ($mountpoint != "") {
echo "<mountpoint>".$mountpoint."</mountpoint>";
$mountpoint = "";
} else {
echo "<mountpoint>none</mountpoint>";
}
if ($filesystem != "") {
echo "<filesystem>".$filesystem."</filesystem>";
$filesystem = "";
} else {
echo "<filesystem>none</filesystem>";
}
echo "</item>";
}
}
break;
case "mkdir":
$dir_name = $_GET['name'];
if (isset($dir_name) && (($dir_name != "") || ($dir_name != " ")))
{
exec('mkdir '.SSD_ROOT.$dir_name);
echo "done";
break;
}
else
break;
case "dir_prefix": // combines mkdir with set_prefix define('SSD_ROOT', '/mnt/sda1/');
$dir_name = $_GET['name'];
if (isset($dir_name) && (($dir_name != "") || ($dir_name != " ")))
{
exec('mkdir '.SSD_ROOT.$dir_name);
fprintf($fcmd, "prefix=%s;\n", SSD_ROOT.$prefix.$dir_name.'/');
echo "done";
break;
}
else
break;
case "is_hdd_mounted":
if (isset($_GET['partition']))
$partition = $_GET['partition'];
else
$partition = '/dev/sda1';
//$partition = '/dev/hda1';
exec('mount', $arr);
$mounted = implode("", $arr);
if (strstr($mounted, $partition))
echo substr($mounted, strpos($mounted, $partition),22);
else
echo "no HDD mounted";
break;
case "create_symlink":
//exec('ln -s /mnt/sda1 /mnt/flash/html/hdd');
if (isset($_GET['mountpoint'])) $mountpoint = $_GET['mountpoint'];
else $mountpoint = "/mnt/sda1";
exec("rm /www/pages/hdd");
exec("ln -sf $mountpoint /www/pages/hdd");
break;
// case "list":
// if (isset($_GET['path'])) $path = $_GET['path'];
// else {
// echo "the path is not set";
// break;
// }
//
// if (is_dir($path)) {
// $files = scandir($path);
// foreach ($files as $file){
// if (is_file("$path/$file")) echo "<f>$path/$file</f>";
// }
// }else{
// echo "directory not found";
// break;
// }
//
// break;
case "list_files":
if (!file_exists('/www/pages/hdd')) {
echo "no webshare found";
break;
}
$dir = $_GET["dir"];
if (isset($dir) && ($dir != "") && ($dir != "/./") && ($dir != "/")) // show "one level up" item if we are not in "home" directory
{
echo "<file>";
echo "<type>updir</type>";
echo "<name>..</name>";
$file_remove_last_slash = substr($dir, 0, strlen($dir)-1);
$file_pos_of_second_last_slash = strrpos($file_remove_last_slash, "/");
$up_file = substr($dir, 0, $file_pos_of_second_last_slash+1);
while(strpos($up_file, "//")) {
$up_file = str_replace("//", "/", $up_file);
}
if ($up_file == "")
echo "<path>/</path>";
else
echo "<path>".$up_file."</path>";
echo "<size>0</size>";
echo "<date>0</date>";
echo "</file>";
}
if ($handle = opendir('/www/pages/hdd/'.$dir)) {
while ($file = readdir($handle))
{
if ($file != "." && $file != "..")
{
echo "<file>";
echo "<type>";
if (is_dir("/www/pages/hdd/".$dir.$file))
echo "dir";
else
echo $extension = substr($file, strrpos($file, '.')+1, strlen($file));
echo "</type>";
echo "<name>".$file."</name>";
echo "<path>".substr($dir, 1).$file."</path>";
$size = filesize("/www/pages/hdd/".$dir.$file);
echo "<size>".$size."</size>";
if(!ini_get('date.timezone')){
date_default_timezone_set('GMT');
}
$date = date ("d M Y H:i:s", filectime("/www/pages/hdd/".$dir.$file));
echo "<date>".$date."</date>";
echo "</file>";
}
}
closedir($handle);
}else{
echo "no webshare found<br>";
}
break;
case "set_prefix":
$prefix = $_GET['prefix'];
fprintf($fcmd, "prefix=%s;\n", $prefix);
// setcookie("directory", $prefix);
break;
case "set_debuglev":
$debuglev = $_GET['debuglev'];
fprintf($fcmd, "debuglev=%s;\n", $debuglev);
break;
case "set_duration":
$duration = $_GET['duration'];
fprintf($fcmd, "duration=%s;\n", $duration);
break;
case "set_size":
$size = $_GET['size'];
fprintf($fcmd, "length=%s;\n", $size);
break;
case "set_max_frames":
$max_frames = $_GET['max_frames'];
fprintf($fcmd, "max_frames=%s;\n", $max_frames);
break;
case "set_frames_per_chunk":
$frames_per_chunk = $_GET['frames_per_chunk'];
fprintf($fcmd, "frames_per_chunk=%s;\n", $frames_per_chunk);
break;
case "set_start_after_timestamp":
$start_after_timestamp = $_GET['start_after_timestamp'];
// Allow setting start timestamp as relative time with "p3" = plus 3 second
// This allows triggering recording in the future without first reading current camera time
if (substr($start_after_timestamp, 0, 1) == "p") {
$start_after_timestamp = elphel_get_fpga_time() + substr($start_after_timestamp, 1) ;
//echo "now: ".elphel_get_fpga_time()." relative: ".$start_after_timestamp; //debug
}
fprintf($fcmd, "start_after_timestamp=%s;\n", $start_after_timestamp);
break;
case "set_frameskip":
$frameskip_value = $_GET['frameskip'];
fprintf($fcmd, "frameskip=%s;\n", $frameskip_value);
break;
case "set_timelapse":
$timelapse_value = $_GET['timelapse'];
fprintf($fcmd, "timelapse=%s;\n", $timelapse_value);
break;
case "init_compressor":
$sensor_port = $_GET['sensor_port'];
elphel_compressor_run($sensor_port);
break;
case "check_audio_hardware":
exec('arecord -l', $arr1);
$audio_hardware = implode("", $arr1);
if ($audio_hardware == "")
echo "no Audio Hardware detected";
else
{
$message = substr($audio_hardware, strpos($audio_hardware, "],")+2);
$message = substr($message, 1, strpos($message, "[")-2);
echo $message;
}
break;
case "test_audio_playback":
$soundfile = $_GET['soundfile'];
exec('aplay '.$soundfile);
break;
case "setmov":
exec('echo "format=mov;" > '.$cmd_pipe); // Set quicktime *.mov as default format after startup.
exec('echo "save_gp=1;\n" > '.$cmd_pipe); // enable calculation of free/used buffer space
break;
case "setjpeg":
exec('echo "format=jpg;" > '.$cmd_pipe); // Set quicktime *.mov as default format after startup.
exec('echo "save_gp=1;\n" > '.$cmd_pipe); // enable calculation of free/used buffer space
break;
case "setrawdevpath":
$rawdev_path = $_GET['path'];
exec('echo "rawdev_path='.$rawdev_path.';" > '.$cmd_pipe);
break;
case "gettime":
echo elphel_get_fpga_time();
break;
case "set_dummy_read":
$dummy_read = $_GET["dummy_read"];
exec('echo "dummy_read='.$dummy_read.';" > '.$cmd_pipe);
break;
}
if ($fcmd)
fclose($fcmd);
echo "</".$cmd.">";
xml_footer();
}
function xml_header() {
header("Content-type: text/xml");
header("Pragma: no-cache\n");
// allow CORS: needed for multi cams unified control
header('Access-Control-Allow-Origin: *');
echo "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
echo "<camogm_interface>\n";
}
function xml_footer() {
echo "</camogm_interface>\n";
}
/** Get a list of suitable partitions. The list will contain SATA devices only and
* will have the following format: "name" => "size_in_blocks".
*/
function get_partitions()
{
$names = array();
$regexp = '/([0-9]+) +(sd[a-z0-9]+$)/';
exec("cat /proc/partitions", $partitions);
// the first two elements of an array are table header and empty line delimiter, skip them
for ($i = 2; $i < count($partitions); $i++) {
// select SATA devices only
if (preg_match($regexp, $partitions[$i], $name) == 1) {
$names[$name[2]] = $name[1];
$j++;
}
}
return $names;
}
/** Get a list of disk devices which have file system and can be mounted. This function
* uses 'blkid' command from busybox.
*/
function get_mnt_dev()
{
$partitions = get_partitions();
$devices = array();
$fs_types = array();
foreach ($partitions as $partition => $size) {
$res = array();
$dev = "/dev/" . $partition;
if (!empty(ASSUME_EXT4)) { // avoiding I/O operations with /dev/sda
if ($partition == ASSUME_EXT4) {
$res = "ext4";
} else {
$res = "";
}
} else {
exec("blkid " . $dev, $res);
}
if (!empty($res)) {
$devices[$i] = preg_replace('/: +.*/', "", $res[0]);
if (preg_match('/(?<=TYPE=")[a-z0-9]+(?=")/', $res[0], $fs) == 1)
$fs_types[$i] = $fs[0];
else
$fs_types[$i] = "none";
$i++;
}
}
return array("devices" => $devices, "types" => $fs_types);
}
/** Get a list of devices whithout file system which can be used for raw disk storage from camogm. */
function get_raw_dev()
{
$j = 0;
$ret = get_mnt_dev();
$devices = $ret["devices"];
$types = $ret["types"];
$names = get_partitions();
// filter out partitions with file system
$i = 0;
$raw_devices = array();
foreach ($names as $name => $size) {
$found = false;
foreach ($devices as $device) {
if (strpos($device, $name) !== false)
$found = true;
}
if ($found === false) {
// current partition is not found in the blkid list, add it to raw devices
$raw_devices["/dev/" . $name] = $size;
$i++;
}
}
//special case
if (count($raw_devices)>1) {
foreach($raw_devices as $k=>$v){
if (preg_match('/sd[a-z][0-9]/',$k)==0) {
unset($raw_devices[$k]);
}
}
}
return $raw_devices;
}
/** Check if camera was booted from NAND or SD card and modify the path where camogm will save
* disk write pointer. */
function get_state_path()
{
global $default_state;
$prefix = '/tmp/rootfs.ro';
if (file_exists($prefix)) {
$ret = $prefix . $default_state;
} else {
$ret = $default_state;
}
return $ret;
}
/** Write command to camogm command pipe */
function write_cmd_pipe($cmd_str)
{
global $cmd_pipe;
$fcmd = fopen($cmd_pipe, 'w');
if ($fcmd !== false) {
fprintf($fcmd, $cmd_str);
fflush($fcmd);
fclose($fcmd);
}
}
?>
...@@ -563,7 +563,7 @@ ...@@ -563,7 +563,7 @@
<tr><td>Audio Recording:</td><td id="ajax_audio_recording">loading...</td></tr> <tr><td>Audio Recording:</td><td id="ajax_audio_recording">loading...</td></tr>
<tr><td>Geo-Tagging:</td><td id="ajax_geotag_enabled"><? if($xml_geotagging_enabled == "yes") echo "enabled"; else echo "disabled"; ?></td></tr> <tr><td>Geo-Tagging:</td><td id="ajax_geotag_enabled"><? if($xml_geotagging_enabled == "yes") echo "enabled"; else echo "disabled"; ?></td></tr>
<tr><td>Filename:</td><td id="ajax_file_name">-</td></tr> <tr><td>Filename:</td><td id="ajax_file_name">-</td></tr>
<tr><td>Record Time:</td><td id="ajax_file_duration">-</td></tr> <tr><td>Combined Channels Record Time:</td><td id="ajax_file_duration">-</td></tr>
<tr><td>File Size:</td><td id="ajax_file_length">-</td></tr> <tr><td>File Size:</td><td id="ajax_file_length">-</td></tr>
<tr><td>Data Rate:</td><td id="ajax_data_rate">-</td></tr> <tr><td>Data Rate:</td><td id="ajax_data_rate">-</td></tr>
<tr><td>Data Rate:</td><td id="ajax_data_rate2">-</td></tr> <tr><td>Data Rate:</td><td id="ajax_data_rate2">-</td></tr>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment