mirror of
				https://github.com/gtxaspec/wz_mini_hacks.git
				synced 2025-11-04 06:31:54 +00:00 
			
		
		
		
	Merge branch 'master' into Fix_Workaround_Issue_145
This commit is contained in:
		@@ -94,6 +94,11 @@ fi
 | 
			
		||||
 | 
			
		||||
/opt/wz_mini/etc/init.d/wz_user.sh &
 | 
			
		||||
 | 
			
		||||
if [[ "$DISABLE_MOTOR" == "true" ]]; then
 | 
			
		||||
	echo "Motor Disabled"
 | 
			
		||||
	touch /opt/wz_mini/tmp/.ms
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
##LIBRARY DEBUG
 | 
			
		||||
#cp /opt/wz_mini/lib/uClibc.tar /tmp
 | 
			
		||||
#tar -xf /tmp/uClibc.tar -C /tmp
 | 
			
		||||
 
 | 
			
		||||
@@ -88,6 +88,7 @@ DISABLE_FW_UPGRADE="false"
 | 
			
		||||
AUDIO_PROMPT_VOLUME="50"
 | 
			
		||||
ENABLE_MP4_WRITE="false"
 | 
			
		||||
NIGHT_DROP_DISABLE="false"
 | 
			
		||||
DISABLE_MOTOR="false"
 | 
			
		||||
 | 
			
		||||
#####DEBUG#####
 | 
			
		||||
#drops you to a shell via serial, doesn't load app_init.sh
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@@ -88,6 +88,7 @@ DISABLE_FW_UPGRADE="false"
 | 
			
		||||
AUDIO_PROMPT_VOLUME="50"
 | 
			
		||||
ENABLE_MP4_WRITE="false"
 | 
			
		||||
NIGHT_DROP_DISABLE="false"
 | 
			
		||||
DISABLE_MOTOR="false"
 | 
			
		||||
 | 
			
		||||
#####DEBUG#####
 | 
			
		||||
#drops you to a shell via serial, doesn't load app_init.sh
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								file.chk
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								file.chk
									
									
									
									
									
								
							@@ -5,10 +5,10 @@ d41d8cd98f00b204e9800998ecf8427e  SD_ROOT/wz_mini/mnt/.gitignore
 | 
			
		||||
ad7d1a2f9db3079617731b5854ce3b6a  SD_ROOT/wz_mini/etc/init.d/wz_cam.sh
 | 
			
		||||
0774518c06d6ef8e7181d35f194777cc  SD_ROOT/wz_mini/etc/init.d/wz_init.sh
 | 
			
		||||
0abc8c502bded3b056ac64ab72e76f3f  SD_ROOT/wz_mini/etc/init.d/wz_user.sh
 | 
			
		||||
22d8154a9d2b66b381b9f4188afc6357  SD_ROOT/wz_mini/etc/init.d/wz_post.sh
 | 
			
		||||
65c7dab024c6df1107dbfb065f05a751  SD_ROOT/wz_mini/etc/init.d/wz_post.sh
 | 
			
		||||
e3034eac02d8eda9902ca9cf89f0a586  SD_ROOT/wz_mini/etc/inittab
 | 
			
		||||
840aa9c26726201f7cffbf001bee193a  SD_ROOT/wz_mini/etc/uvc_jxf22.config
 | 
			
		||||
7c9d57b1b1b8bbdddfb248565ce02cb4  SD_ROOT/wz_mini/etc/wz_mini.conf.dist
 | 
			
		||||
7701fde345655472250dee076fb0b065  SD_ROOT/wz_mini/etc/wz_mini.conf.dist
 | 
			
		||||
8b5e58acfcbb20034dc4873a08b45fd9  SD_ROOT/wz_mini/etc/profile
 | 
			
		||||
2c2df1b9cb603f9c31c46162d6ac307f  SD_ROOT/wz_mini/etc/alsa/alsa.conf
 | 
			
		||||
9e5591da95042bcca910403bde25dc60  SD_ROOT/wz_mini/etc/fstab
 | 
			
		||||
@@ -84,7 +84,7 @@ b339aee882a5d1c943ad08e4282ec3fd  SD_ROOT/wz_mini/usr/bin/iCamera-dbg
 | 
			
		||||
4c780f0455481d106d47d89f0ae04ed5  SD_ROOT/wz_mini/lib/uClibc.tar
 | 
			
		||||
9afeb088e4cbabbe0b04033b560204d0  SD_ROOT/wz_mini/lib/libimp.so
 | 
			
		||||
4100755cb6cc6e3b76da20c7e3690e16  SD_ROOT/wz_mini/lib/libalog.so
 | 
			
		||||
d63e45dd1a05a62ad91ef3d70eae44de  SD_ROOT/wz_mini/lib/libcallback.so
 | 
			
		||||
ea6430bf3016b82871088c07640490b1  SD_ROOT/wz_mini/lib/libcallback.so
 | 
			
		||||
b730b26986b36c49a5c9edb7fe1422be  SD_ROOT/wz_mini/lib/modules/3.10.14/modules.order
 | 
			
		||||
e458a5a0f017c68c2fb5658f1f0aeaf7  SD_ROOT/wz_mini/lib/modules/3.10.14/modules.devname
 | 
			
		||||
0fe2c09c560007790def301c0e9df33f  SD_ROOT/wz_mini/lib/modules/3.10.14/modules.alias.bin
 | 
			
		||||
@@ -224,7 +224,7 @@ aafb0749425838f41e68ecced758ab6c  SD_ROOT/wz_mini/lib/modules/3.10.14__isvp_swan
 | 
			
		||||
14865a6e2e2df87a8362c6f20377a934  SD_ROOT/wz_mini/lib/libtinyalsa.so.2
 | 
			
		||||
bd383994491e4bdca81788c168feb2eb  SD_ROOT/wz_mini/lib/libasound.so.2
 | 
			
		||||
f6f0d5a9ebd916de6bdb9695067809ae  SD_ROOT/wz_mini/lib/libaudioProcess.so
 | 
			
		||||
7c9d57b1b1b8bbdddfb248565ce02cb4  SD_ROOT/wz_mini/wz_mini.conf
 | 
			
		||||
7701fde345655472250dee076fb0b065  SD_ROOT/wz_mini/wz_mini.conf
 | 
			
		||||
d41d8cd98f00b204e9800998ecf8427e  SD_ROOT/wz_mini/tmp/.gitignore
 | 
			
		||||
090bdf50db1c1d05720f276295ac17ca  v2_install/compile_image.sh
 | 
			
		||||
ff15869fe24297b9a5f75335a458a44f  v2_install/fw_tool.sh
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
# libcallback.so
 | 
			
		||||
 | 
			
		||||
CC = /openmiko/build/mips-gcc472-glibc216-64bit/bin/mips-linux-uclibc-gnu-gcc
 | 
			
		||||
CFLAGS = -fPIC -std=gnu99 -shared -ldl -ltinyalsa -lm -pthread
 | 
			
		||||
CC_SRCS = video_callback.c audio_callback.c jpeg.c setlinebuf.c mmc_format.c curl.c freopen.c opendir.c remove.c motor.c command.c gmtime_r.c wait_motion.c irled.c audio_play.c mp4write.c imp_control.c night_drop.c
 | 
			
		||||
TARGET = libcallback.so
 | 
			
		||||
 | 
			
		||||
all: ${TARGET}
 | 
			
		||||
 | 
			
		||||
${TARGET}: ${CC_SRCS}
 | 
			
		||||
	${CC} ${CFLAGS} -o ${TARGET} ${CC_SRCS}
 | 
			
		||||
@@ -1,180 +0,0 @@
 | 
			
		||||
#define _GNU_SOURCE
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <tinyalsa/pcm.h>
 | 
			
		||||
 | 
			
		||||
struct frames_st {
 | 
			
		||||
  void *buf;
 | 
			
		||||
  size_t length;
 | 
			
		||||
};
 | 
			
		||||
typedef int (* framecb)(struct frames_st *);
 | 
			
		||||
 | 
			
		||||
static uint32_t (*real_local_sdk_audio_set_pcm_frame_callback)(int ch, void *callback);
 | 
			
		||||
static void *audio_pcm_cb = NULL;
 | 
			
		||||
static int AudioCaptureEnable = 0;
 | 
			
		||||
 | 
			
		||||
static void *audio_pcm_cb1 = NULL;
 | 
			
		||||
static int AudioCaptureEnable1 = 0;
 | 
			
		||||
 | 
			
		||||
char *AudioCapture(int fd, char *tokenPtr) {
 | 
			
		||||
 | 
			
		||||
  char *p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
  if(!p) return AudioCaptureEnable ? "on" : "off";
 | 
			
		||||
  if(!strcmp(p, "on")) {
 | 
			
		||||
    AudioCaptureEnable = 1;
 | 
			
		||||
    fprintf(stderr, "[command] audio capute on\n", p);
 | 
			
		||||
    return "ok";
 | 
			
		||||
  }
 | 
			
		||||
  if(!strcmp(p, "on1")) {
 | 
			
		||||
    AudioCaptureEnable1 = 1;
 | 
			
		||||
    fprintf(stderr, "[command] audio capute on\n", p);
 | 
			
		||||
    return "ok";
 | 
			
		||||
  }
 | 
			
		||||
  if(!strcmp(p, "off")) {
 | 
			
		||||
    AudioCaptureEnable = 0;
 | 
			
		||||
    fprintf(stderr, "[command] audio capute off\n", p);
 | 
			
		||||
    return "ok";
 | 
			
		||||
  }
 | 
			
		||||
  if(!strcmp(p, "off1")) {
 | 
			
		||||
    AudioCaptureEnable1 = 0;
 | 
			
		||||
    fprintf(stderr, "[command] audio capute off\n", p);
 | 
			
		||||
    return "ok";
 | 
			
		||||
  }
 | 
			
		||||
  return "error";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//channel 0
 | 
			
		||||
static uint32_t audio_pcm_capture(struct frames_st *frames) {
 | 
			
		||||
 | 
			
		||||
  static struct pcm *pcm = NULL;
 | 
			
		||||
  static int firstEntry = 0;
 | 
			
		||||
  uint32_t *buf = frames->buf;
 | 
			
		||||
 | 
			
		||||
  static int snd_rate = 16000;
 | 
			
		||||
  const char *productv2="/driver/sensor_jxf23.ko";
 | 
			
		||||
 | 
			
		||||
    //Change sample rate to 8000 if we are a V2 Camera
 | 
			
		||||
    if( access( productv2, F_OK ) == 0 ) {
 | 
			
		||||
      snd_rate = 8000;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  if(!firstEntry) {
 | 
			
		||||
    firstEntry++;
 | 
			
		||||
    unsigned int card = 0;
 | 
			
		||||
    unsigned int device = 1;
 | 
			
		||||
    int flags = PCM_OUT | PCM_MMAP;
 | 
			
		||||
    const struct pcm_config config = {
 | 
			
		||||
      .channels = 1,
 | 
			
		||||
      .rate = snd_rate,
 | 
			
		||||
      .format = PCM_FORMAT_S16_LE,
 | 
			
		||||
      .period_size = 128,
 | 
			
		||||
      .period_count = 8,
 | 
			
		||||
      .start_threshold = 320,
 | 
			
		||||
      .silence_threshold = 0,
 | 
			
		||||
      .silence_size = 0,
 | 
			
		||||
      .stop_threshold = 320 * 4
 | 
			
		||||
    };
 | 
			
		||||
    pcm = pcm_open(card, device, flags, &config);
 | 
			
		||||
    if(pcm == NULL) {
 | 
			
		||||
        fprintf(stderr, "failed to allocate memory for PCM CH0\n");
 | 
			
		||||
    } else if(!pcm_is_ready(pcm)) {
 | 
			
		||||
      pcm_close(pcm);
 | 
			
		||||
      fprintf(stderr, "failed to open PCM CH0\n");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(pcm && AudioCaptureEnable) {
 | 
			
		||||
    int avail = pcm_mmap_avail(pcm);
 | 
			
		||||
    int delay = pcm_get_delay(pcm);
 | 
			
		||||
    int ready = pcm_is_ready(pcm);
 | 
			
		||||
    int err = pcm_writei(pcm, buf, pcm_bytes_to_frames(pcm, frames->length));
 | 
			
		||||
    if(err < 0) fprintf(stderr, "pcm_writei err=%d\n", err);
 | 
			
		||||
  }
 | 
			
		||||
  return ((framecb)audio_pcm_cb)(frames);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//channel1
 | 
			
		||||
static uint32_t audio_pcm_capture1(struct frames_st *frames) {
 | 
			
		||||
 | 
			
		||||
  static struct pcm *pcm = NULL;
 | 
			
		||||
  static int firstEntry = 0;
 | 
			
		||||
  uint32_t *buf = frames->buf;
 | 
			
		||||
 | 
			
		||||
  if(!firstEntry) {
 | 
			
		||||
    firstEntry++;
 | 
			
		||||
    unsigned int card = 0;
 | 
			
		||||
    unsigned int device = 0;
 | 
			
		||||
    int flags = PCM_OUT | PCM_MMAP;
 | 
			
		||||
    const struct pcm_config config = {
 | 
			
		||||
      .channels = 1,
 | 
			
		||||
      .rate = 8000,
 | 
			
		||||
      .format = PCM_FORMAT_S16_LE,
 | 
			
		||||
      .period_size = 128,
 | 
			
		||||
      .period_count = 8,
 | 
			
		||||
      .start_threshold = 320,
 | 
			
		||||
      .silence_threshold = 0,
 | 
			
		||||
      .silence_size = 0,
 | 
			
		||||
      .stop_threshold = 320 * 4
 | 
			
		||||
    };
 | 
			
		||||
    pcm = pcm_open(card, device, flags, &config);
 | 
			
		||||
    if(pcm == NULL) {
 | 
			
		||||
        fprintf(stderr, "failed to allocate memory for PCM CH1\n");
 | 
			
		||||
    } else if(!pcm_is_ready(pcm)) {
 | 
			
		||||
      pcm_close(pcm);
 | 
			
		||||
      fprintf(stderr, "failed to open PCM CH1\n");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(pcm && AudioCaptureEnable1) {
 | 
			
		||||
    int avail = pcm_mmap_avail(pcm);
 | 
			
		||||
    int delay = pcm_get_delay(pcm);
 | 
			
		||||
    int ready = pcm_is_ready(pcm);
 | 
			
		||||
    int err = pcm_writei(pcm, buf, pcm_bytes_to_frames(pcm, frames->length));
 | 
			
		||||
    if(err < 0) fprintf(stderr, "pcm_writei err=%d\n", err);
 | 
			
		||||
  }
 | 
			
		||||
  return ((framecb)audio_pcm_cb1)(frames);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t local_sdk_audio_set_pcm_frame_callback(int ch, void *callback) {
 | 
			
		||||
 | 
			
		||||
  fprintf(stderr, "local_sdk_audio_set_pcm_frame_callback streamChId=%d, callback=0x%x\n", ch, callback);
 | 
			
		||||
 | 
			
		||||
  static int ch_count = 0;
 | 
			
		||||
 | 
			
		||||
  if( (ch == 0) && ch_count == 0) {
 | 
			
		||||
    audio_pcm_cb = callback;
 | 
			
		||||
    fprintf(stderr,"enc func injection CH0 save audio_pcm_cb=0x%x\n", audio_pcm_cb);
 | 
			
		||||
    callback = audio_pcm_capture;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if( (ch == 1) && ch_count == 1) {
 | 
			
		||||
    audio_pcm_cb1 = callback;
 | 
			
		||||
    fprintf(stderr,"enc func injection CH1 save audio_pcm_cb=0x%x\n", audio_pcm_cb1);
 | 
			
		||||
    callback = audio_pcm_capture1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
//if V2 here, we have to latch on to the same callback as CH0, since the V2's only have one audio callback
 | 
			
		||||
 const char *productv2="/driver/sensor_jxf23.ko";
 | 
			
		||||
 if( access( productv2, F_OK ) == 0 ) {
 | 
			
		||||
  if( (ch == 0) && ch_count == 1) {
 | 
			
		||||
    audio_pcm_cb1 = callback;
 | 
			
		||||
    fprintf(stderr,"enc func injection CH0 second callback for V2 save audio_pcm_cb=0x%x\n", audio_pcm_cb1);
 | 
			
		||||
    callback = audio_pcm_capture1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
  ch_count=ch_count+1;
 | 
			
		||||
 | 
			
		||||
  return real_local_sdk_audio_set_pcm_frame_callback(ch, callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) audio_callback_init(void) {
 | 
			
		||||
 | 
			
		||||
  real_local_sdk_audio_set_pcm_frame_callback = dlsym(dlopen("/system/lib/liblocalsdk.so", RTLD_LAZY), "local_sdk_audio_set_pcm_frame_callback");
 | 
			
		||||
}
 | 
			
		||||
@@ -1,126 +0,0 @@
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
extern void local_sdk_speaker_set_pa_mode(int mode);
 | 
			
		||||
extern void local_sdk_speaker_set_ap_mode(int mode);
 | 
			
		||||
extern void local_sdk_speaker_clean_buf_data();
 | 
			
		||||
extern void local_sdk_speaker_set_volume(int volume);
 | 
			
		||||
extern int local_sdk_speaker_feed_pcm_data(unsigned char *buf, int size);
 | 
			
		||||
extern void local_sdk_speaker_finish_buf_data();
 | 
			
		||||
extern void CommandResponse(int fd, const char *res);
 | 
			
		||||
 | 
			
		||||
static pthread_mutex_t AudioPlayMutex = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
static int AudioPlayFd = -1;
 | 
			
		||||
static char waveFile[256];
 | 
			
		||||
static int Volume = 0;
 | 
			
		||||
 | 
			
		||||
int PlayPCM(char *file, int vol) {
 | 
			
		||||
 | 
			
		||||
  static const int waveHeaderLength = 44;
 | 
			
		||||
  static const int bufLength = 640;
 | 
			
		||||
  unsigned char buf[bufLength];
 | 
			
		||||
  const unsigned char cmp[] = {
 | 
			
		||||
    0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20,
 | 
			
		||||
    0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x40, 0x1f, 0x00, 0x00, 0x80, 0x3e, 0x00, 0x00,
 | 
			
		||||
    0x02, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  fprintf(stderr, "[command] aplay: file:%s\n", file);
 | 
			
		||||
  FILE *fp = fopen(file, "rb");
 | 
			
		||||
  if(fp == NULL) {
 | 
			
		||||
    fprintf(stderr, "[command] aplay err: fopen %s failed!\n", file);
 | 
			
		||||
    return -1;
 | 
			
		||||
  } else {
 | 
			
		||||
    size_t size = fread(buf, 1, waveHeaderLength, fp);
 | 
			
		||||
    if(size != waveHeaderLength) {
 | 
			
		||||
      fprintf(stderr, "[command] aplay err: header size error\n");
 | 
			
		||||
    }
 | 
			
		||||
    buf[4] = buf[5] = buf[6] = buf[7] = 0;
 | 
			
		||||
    if(memcmp(buf, cmp, waveHeaderLength - 4)) {
 | 
			
		||||
      fprintf(stderr, "[command] aplay err: header error\n");
 | 
			
		||||
    }
 | 
			
		||||
    local_sdk_speaker_clean_buf_data();
 | 
			
		||||
    local_sdk_speaker_set_volume(vol);
 | 
			
		||||
 | 
			
		||||
 if(!local_sdk_speaker_set_pa_mode) {
 | 
			
		||||
    local_sdk_speaker_set_ap_mode(3);
 | 
			
		||||
      fprintf(stderr, "[command] aplay: set ap mode 3\n");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 if(!local_sdk_speaker_set_ap_mode) {
 | 
			
		||||
    local_sdk_speaker_set_pa_mode(3);
 | 
			
		||||
      fprintf(stderr, "[command] aplay: set pa mode 3\n");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    while(!feof(fp)) {
 | 
			
		||||
      size = fread(buf, 1, bufLength, fp);
 | 
			
		||||
      if (size <= 0) break;
 | 
			
		||||
      while(local_sdk_speaker_feed_pcm_data(buf, size)) usleep(100 * 1000);
 | 
			
		||||
    }
 | 
			
		||||
    fclose(fp);
 | 
			
		||||
    usleep(2 * 1000 * 1000);
 | 
			
		||||
    local_sdk_speaker_finish_buf_data();
 | 
			
		||||
    local_sdk_speaker_set_volume(0);
 | 
			
		||||
 | 
			
		||||
 if(!local_sdk_speaker_set_pa_mode) {
 | 
			
		||||
    local_sdk_speaker_set_ap_mode(0);
 | 
			
		||||
  }
 | 
			
		||||
 if(!local_sdk_speaker_set_ap_mode) {
 | 
			
		||||
    local_sdk_speaker_set_pa_mode(0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
  fprintf(stderr, "[command] aplay: finish\n");
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *AudioPlayThread() {
 | 
			
		||||
 | 
			
		||||
  while(1) {
 | 
			
		||||
    pthread_mutex_lock(&AudioPlayMutex);
 | 
			
		||||
    if(AudioPlayFd >= 0) {
 | 
			
		||||
      int res = PlayPCM(waveFile, Volume);
 | 
			
		||||
      CommandResponse(AudioPlayFd, res ? "error" : "ok");
 | 
			
		||||
    }
 | 
			
		||||
    AudioPlayFd = -1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *AudioPlay(int fd, char *tokenPtr) {
 | 
			
		||||
 | 
			
		||||
  if(AudioPlayFd >= 0) {
 | 
			
		||||
    fprintf(stderr, "[command] aplay err: Previous file is still playing. %d %d\n", AudioPlayFd, fd);
 | 
			
		||||
    return "error";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  char *p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
  if(!p) {
 | 
			
		||||
    fprintf(stderr, "[command] aplay err: usage : aplay <wave file> [<volume>]\n");
 | 
			
		||||
    return "error";
 | 
			
		||||
  }
 | 
			
		||||
  strncpy(waveFile, p, 255);
 | 
			
		||||
 | 
			
		||||
  p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
  Volume = 40;
 | 
			
		||||
  if(p) Volume = atoi(p);
 | 
			
		||||
 | 
			
		||||
  AudioPlayFd = fd;
 | 
			
		||||
  pthread_mutex_unlock(&AudioPlayMutex);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) AudioPlayInit(void) {
 | 
			
		||||
 | 
			
		||||
  pthread_mutex_lock(&AudioPlayMutex);
 | 
			
		||||
  pthread_t thread;
 | 
			
		||||
  if(pthread_create(&thread, NULL, AudioPlayThread, NULL)) {
 | 
			
		||||
    fprintf(stderr, "pthread_create error\n");
 | 
			
		||||
    pthread_mutex_unlock(&AudioPlayMutex);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,197 +0,0 @@
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
static const unsigned short CommandPort = 4000;
 | 
			
		||||
static int SelfPipe[2];
 | 
			
		||||
 | 
			
		||||
extern char *JpegCapture(int fd, char *tokenPtr);
 | 
			
		||||
extern char *VideoCapture(int fd, char *tokenPtr);
 | 
			
		||||
extern char *AudioCapture(int fd, char *tokenPtr);
 | 
			
		||||
extern char *MotorMove(int fd, char *tokenPtr);
 | 
			
		||||
extern char *WaitMotion(int fd, char *tokenPtr);
 | 
			
		||||
extern char *IrLed(int fd, char *tokenPtr);
 | 
			
		||||
extern char *AudioPlay(int fd, char *tokenPtr);
 | 
			
		||||
extern char *mp4Write(int fd, char *tokenPtr);
 | 
			
		||||
extern char *imp_Control(int fd, char *tokenPtr);
 | 
			
		||||
 | 
			
		||||
struct CommandTableSt {
 | 
			
		||||
  const char *cmd;
 | 
			
		||||
  char * (*func)(int, char *);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct CommandTableSt CommandTable[] = {
 | 
			
		||||
  { "video",      &VideoCapture },
 | 
			
		||||
  { "audio",      &AudioCapture },
 | 
			
		||||
  { "jpeg",       &JpegCapture },
 | 
			
		||||
  { "move",       &MotorMove },
 | 
			
		||||
  { "waitMotion", &WaitMotion },
 | 
			
		||||
  { "irled",      &IrLed },
 | 
			
		||||
  { "aplay",      &AudioPlay },
 | 
			
		||||
  { "mp4write",      &mp4Write },
 | 
			
		||||
  { "imp_control",      &imp_Control },
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void CommandResponse(int fd, const char *res) {
 | 
			
		||||
 | 
			
		||||
  unsigned char buf[256];
 | 
			
		||||
  buf[0] = strlen(res) + 1;
 | 
			
		||||
  buf[1] = fd;
 | 
			
		||||
  strncpy((char *)buf + 2, res, 253);
 | 
			
		||||
  write(SelfPipe[1], &buf, buf[0] + 2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *CommandThread(void *arg) {
 | 
			
		||||
 | 
			
		||||
  static const int MaxConnect = 255;
 | 
			
		||||
  int maxFd = 0;
 | 
			
		||||
  fd_set targetFd;
 | 
			
		||||
 | 
			
		||||
  int listenSocket = socket(AF_INET, SOCK_STREAM, 0);
 | 
			
		||||
  if(listenSocket < 0) {
 | 
			
		||||
    fprintf(stderr, "socket : %s\n", strerror(errno));
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  int sock_optval = 1;
 | 
			
		||||
  if(setsockopt(listenSocket, SOL_SOCKET, SO_REUSEADDR,
 | 
			
		||||
                &sock_optval, sizeof(sock_optval)) == -1) {
 | 
			
		||||
    fprintf(stderr, "setsockopt : %s\n", strerror(errno));
 | 
			
		||||
    close(listenSocket);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  struct sockaddr_in saddr;
 | 
			
		||||
  saddr.sin_family = AF_INET;
 | 
			
		||||
  saddr.sin_port = htons(CommandPort);
 | 
			
		||||
  saddr.sin_addr.s_addr = htonl(INADDR_ANY);
 | 
			
		||||
  if(bind(listenSocket, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) {
 | 
			
		||||
    fprintf(stderr, "bind : %s\n", strerror(errno));
 | 
			
		||||
    close(listenSocket);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(listen(listenSocket, MaxConnect) == -1) {
 | 
			
		||||
    fprintf(stderr, "listen : %s\n", strerror(errno));
 | 
			
		||||
    close(listenSocket);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  FD_ZERO(&targetFd);
 | 
			
		||||
  FD_SET(listenSocket, &targetFd);
 | 
			
		||||
  maxFd = listenSocket;
 | 
			
		||||
  FD_SET(SelfPipe[0], &targetFd);
 | 
			
		||||
  maxFd = (SelfPipe[0] > maxFd) ? SelfPipe[0] : maxFd;
 | 
			
		||||
  if(maxFd >= MaxConnect) maxFd = MaxConnect - 1;
 | 
			
		||||
 | 
			
		||||
  while(1) {
 | 
			
		||||
    fd_set checkFDs;
 | 
			
		||||
    memcpy(&checkFDs, &targetFd, sizeof(targetFd));
 | 
			
		||||
    if(select(maxFd + 1, &checkFDs, NULL, NULL, NULL) == -1) {
 | 
			
		||||
      fprintf(stderr, "select error : %s\n", strerror(errno));
 | 
			
		||||
    } else {
 | 
			
		||||
      for(int fd = maxFd; fd >= 0; fd--) {
 | 
			
		||||
        if(FD_ISSET(fd, &checkFDs)) {
 | 
			
		||||
          if(fd == SelfPipe[0]) {
 | 
			
		||||
            while(1) {
 | 
			
		||||
              unsigned char buf[256];
 | 
			
		||||
              int length = read(SelfPipe[0], buf, 2);
 | 
			
		||||
              if(length <= 1) break;
 | 
			
		||||
              int resSize = buf[0];
 | 
			
		||||
              int resFd = buf[1];
 | 
			
		||||
              length = read(SelfPipe[0], buf, resSize);
 | 
			
		||||
              if(length < resSize) break;
 | 
			
		||||
              char *res = (char *)buf;
 | 
			
		||||
              if(strlen(res)) {
 | 
			
		||||
                strcat(res, "\n");
 | 
			
		||||
                send(resFd, res, strlen(res) + 1, 0);
 | 
			
		||||
              }
 | 
			
		||||
              close(resFd);
 | 
			
		||||
              FD_CLR(resFd, &targetFd);
 | 
			
		||||
            }
 | 
			
		||||
          } else if(fd == listenSocket) {
 | 
			
		||||
            struct sockaddr_in dstAddr;
 | 
			
		||||
            int len = sizeof(dstAddr);
 | 
			
		||||
            int newSocket = accept(fd, (struct sockaddr *)&dstAddr, (socklen_t *)&len);
 | 
			
		||||
            if(newSocket < 0) {
 | 
			
		||||
              fprintf(stderr, "Socket::Accept Error\n");
 | 
			
		||||
              continue;
 | 
			
		||||
            }
 | 
			
		||||
            if(strcmp(inet_ntoa(dstAddr.sin_addr), "127.0.0.1")) {
 | 
			
		||||
              fprintf(stderr, "Rejected request from %s\n", inet_ntoa(dstAddr.sin_addr));
 | 
			
		||||
              close(newSocket);
 | 
			
		||||
              continue;
 | 
			
		||||
            }
 | 
			
		||||
            int flag = fcntl(newSocket, F_GETFL, 0);
 | 
			
		||||
            fcntl(newSocket, F_SETFL, O_NONBLOCK|flag);
 | 
			
		||||
            FD_SET(newSocket, &targetFd);
 | 
			
		||||
            maxFd = (newSocket > maxFd) ? newSocket : maxFd;
 | 
			
		||||
            if(maxFd >= MaxConnect) maxFd = MaxConnect - 1;
 | 
			
		||||
          } else {
 | 
			
		||||
            char buf[256];
 | 
			
		||||
            int size = recv(fd, buf, 255, 0);
 | 
			
		||||
            if(!size) {
 | 
			
		||||
              FD_CLR(fd, &targetFd);
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
            if(size < 0) {
 | 
			
		||||
              close(fd);
 | 
			
		||||
              FD_CLR(fd, &targetFd);
 | 
			
		||||
              break;
 | 
			
		||||
            }
 | 
			
		||||
            buf[size] = 0;
 | 
			
		||||
            char *tokenPtr;
 | 
			
		||||
            char *p = strtok_r(buf, " \t\r\n", &tokenPtr);
 | 
			
		||||
            if(!p) continue;
 | 
			
		||||
            int executed = 0;
 | 
			
		||||
            for(int i = 0; i < sizeof(CommandTable) / sizeof(struct CommandTableSt); i++) {
 | 
			
		||||
              if(!strcasecmp(p, CommandTable[i].cmd)) {
 | 
			
		||||
                char *res = (*CommandTable[i].func)(fd, tokenPtr);
 | 
			
		||||
                if(res) {
 | 
			
		||||
                  send(fd, res, strlen(res) + 1, 0);
 | 
			
		||||
                  char cr = '\n';
 | 
			
		||||
                  send(fd, &cr, 1, 0);
 | 
			
		||||
                  close(fd);
 | 
			
		||||
                  FD_CLR(fd, &targetFd);
 | 
			
		||||
                }
 | 
			
		||||
                executed = 1;
 | 
			
		||||
                break;
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
            if(!executed) {
 | 
			
		||||
              char *res = "error";
 | 
			
		||||
              send(fd, res, strlen(res) + 1, 0);
 | 
			
		||||
              close(fd);
 | 
			
		||||
              FD_CLR(fd, &targetFd);
 | 
			
		||||
              fprintf(stderr, "command error : %s\n", p);
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
         }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) command_init(void) {
 | 
			
		||||
 | 
			
		||||
  if(pipe(SelfPipe)) {
 | 
			
		||||
    fprintf(stderr, "pipe error\n");
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  int flag = fcntl(SelfPipe[0], F_GETFL, 0);
 | 
			
		||||
  fcntl(SelfPipe[0], F_SETFL, O_NONBLOCK|flag);
 | 
			
		||||
  flag = fcntl(SelfPipe[1], F_GETFL, 0);
 | 
			
		||||
  fcntl(SelfPipe[1], F_SETFL, O_NONBLOCK|flag);
 | 
			
		||||
 | 
			
		||||
  pthread_t thread;
 | 
			
		||||
  pthread_create(&thread, NULL, CommandThread, NULL);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,125 +0,0 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
 | 
			
		||||
typedef void CURL;
 | 
			
		||||
typedef int CURLcode;
 | 
			
		||||
typedef long long curl_off_t;
 | 
			
		||||
typedef enum {
 | 
			
		||||
  HTTPREQ_NONE,
 | 
			
		||||
  HTTPREQ_GET,
 | 
			
		||||
  HTTPREQ_POST,
 | 
			
		||||
  HTTPREQ_POST_FORM,
 | 
			
		||||
  HTTPREQ_POST_MIME,
 | 
			
		||||
  HTTPREQ_PUT,
 | 
			
		||||
  HTTPREQ_HEAD,
 | 
			
		||||
  HTTPREQ_OPTIONS,
 | 
			
		||||
  HTTPREQ_LAST
 | 
			
		||||
} Curl_HttpReq;
 | 
			
		||||
 | 
			
		||||
static const int CURL_OK = 0;
 | 
			
		||||
const char *methods[] = {
 | 
			
		||||
  "NONE", "GET", "POST", "POST_FORM", "POST_MIME", "PUT", "HEAD", "OPTIONS", "LAST", ""
 | 
			
		||||
};
 | 
			
		||||
static const char *AlarmPath = "/device/v1/alarm/add";
 | 
			
		||||
static const char *DummyRes = "{\"ts\":1641390551000,\"code\":\"1\",\"msg\":\"\",\"data\":{\"alarm_file_list\":[{\"file_type\":1,\"file_suffix\":\"jpg\",\"file_url\":\"https://localhost/hoge.jpg\",\"encryption_algorithm\":0,\"encryption_password\":\"\"},{\"file_type\":2,\"file_suffix\":\"mp4\",\"file_url\":\"https://localhost/fuga.mp4\",\"encryption_algorithm\":0,\"encryption_password\":\"\"}]}}";
 | 
			
		||||
static const char *DummyHost = "https://localhost/";
 | 
			
		||||
 | 
			
		||||
typedef int (*curl_seek_callback)(void *instream, int offset, int origin);
 | 
			
		||||
typedef int (*curl_write_callback)(char *buffer, int size, int nitems, void *outstream);
 | 
			
		||||
 | 
			
		||||
struct SessionHandle {
 | 
			
		||||
  unsigned char padding0[1392];
 | 
			
		||||
  unsigned char padding1[16];
 | 
			
		||||
  void *out; // offset 1392 + 16
 | 
			
		||||
  unsigned char padding2[40];
 | 
			
		||||
  void *postfields; // offset 1392 + 60
 | 
			
		||||
  unsigned char padding3[8];
 | 
			
		||||
  curl_off_t postfieldsize; // offset offset 1392 + 72
 | 
			
		||||
  unsigned char padding4[8];
 | 
			
		||||
  curl_write_callback fwrite_func; // offset 1392 + 88
 | 
			
		||||
  unsigned char padding5[568];
 | 
			
		||||
  Curl_HttpReq httpreq; // offset 1392 + 660
 | 
			
		||||
  unsigned char padding6[664];
 | 
			
		||||
  char *url; // offset 2720 + 0
 | 
			
		||||
  unsigned char padding7[16];
 | 
			
		||||
  unsigned char padding8[988];
 | 
			
		||||
  int httpcode; // offset 3728 + 0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static CURLcode (*original_curl_easy_perform)(CURL *curl);
 | 
			
		||||
static int curl_hook_enable = 0;
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) curl_hook_init(void) {
 | 
			
		||||
  original_curl_easy_perform = dlsym(dlopen("/thirdlib/libcurl.so", RTLD_LAZY), "curl_easy_perform");
 | 
			
		||||
  char *p = getenv("MINIMIZE_ALARM_CYCLE");
 | 
			
		||||
  curl_hook_enable = p && !strcmp(p, "on");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void Dump(const char *str, void *start, int size) {
 | 
			
		||||
  printf("[curl-debug] Dump %s\n", str);
 | 
			
		||||
  for(int i = 0; i < size; i+= 16) {
 | 
			
		||||
    char buf1[256];
 | 
			
		||||
    char buf2[256];
 | 
			
		||||
    sprintf(buf1, "%08x : ", start + i);
 | 
			
		||||
    for(int j = 0; j < 16; j++) {
 | 
			
		||||
      if(i + j >= size) break;
 | 
			
		||||
      unsigned char d = ((unsigned char *)start)[i + j];
 | 
			
		||||
      sprintf(buf1 + strlen(buf1), "%02x ", d);
 | 
			
		||||
      if((d < 0x20) || (d > 0x7f)) d = '.';
 | 
			
		||||
      sprintf(buf2 + j, "%c", d);
 | 
			
		||||
    }
 | 
			
		||||
    printf("%s %s\n", buf1, buf2);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CURLcode curl_easy_perform(struct SessionHandle *data) {
 | 
			
		||||
 | 
			
		||||
  if(!curl_hook_enable) return original_curl_easy_perform(data);
 | 
			
		||||
 | 
			
		||||
  unsigned int ra = 0;
 | 
			
		||||
  asm volatile(
 | 
			
		||||
    "ori %0, $31, 0\n"
 | 
			
		||||
    : "=r"(ra)
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  int method = data->httpreq;
 | 
			
		||||
  if(method > HTTPREQ_LAST) method = HTTPREQ_LAST;
 | 
			
		||||
  printf("[curl-debug] %s %s ra=0x%08x\n", methods[method], data->url, ra);
 | 
			
		||||
  if(data->postfields) {
 | 
			
		||||
    if(data->postfieldsize > 0) {
 | 
			
		||||
      Dump("[curl-debug] post", data->postfields, data->postfieldsize);
 | 
			
		||||
    } else {
 | 
			
		||||
      printf("[curl-debug] post : %s\n", data->postfields);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(data->url && !strcmp(data->url + strlen(data->url) - strlen(AlarmPath), AlarmPath)) {
 | 
			
		||||
    static time_t lastAccess = 0;
 | 
			
		||||
    struct timeval now;
 | 
			
		||||
    gettimeofday(&now, NULL);
 | 
			
		||||
    if(now.tv_sec - lastAccess < 300) {
 | 
			
		||||
      printf("[curl-debug] Dismiss short cycle alarms.\n");
 | 
			
		||||
      memcpy(data->out, DummyRes, strlen(DummyRes));
 | 
			
		||||
      data->httpcode = 200;
 | 
			
		||||
      return CURL_OK;
 | 
			
		||||
    }
 | 
			
		||||
    CURLcode res = original_curl_easy_perform(data);
 | 
			
		||||
    printf("[curl-debug] res=%d\n", res);
 | 
			
		||||
    if(!res) lastAccess = now.tv_sec;
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(data->url && !strncmp(data->url, DummyHost, strlen(DummyHost))) {
 | 
			
		||||
    printf("[curl-debug] skip http-post.\n");
 | 
			
		||||
    data->httpcode = 200;
 | 
			
		||||
    return CURL_OK;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  CURLcode res = original_curl_easy_perform(data);
 | 
			
		||||
  if(data->out) printf("[curl-debug] res : %s\n", data->out);
 | 
			
		||||
  printf("[curl-debug] ret: %d\n", res);
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
static FILE * (*original_freopen)(const char *pathname, const char *mode, FILE *stream);
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) freopen_hook_init(void) {
 | 
			
		||||
 | 
			
		||||
  original_freopen = dlsym(dlopen ("/lib/libc.so.0", RTLD_LAZY), "freopen");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
FILE *freopen(const char *pathname, const char *mode, FILE *stream) {
 | 
			
		||||
 | 
			
		||||
  if(stream == stdout) return stdout;
 | 
			
		||||
  return original_freopen(pathname, mode, stream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
 | 
			
		||||
extern int MotorFd;
 | 
			
		||||
extern struct timeval MotorLastMovedTime;
 | 
			
		||||
 | 
			
		||||
static struct tm *(*original_gmtime_r)(const time_t *timep, struct tm *result);
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) gmtime_r_hook_init(void) {
 | 
			
		||||
 | 
			
		||||
  original_gmtime_r = dlsym(dlopen ("/lib/libc.so.0", RTLD_LAZY), "gmtime_r");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct tm *gmtime_r(const time_t *timep, struct tm *result) {
 | 
			
		||||
 | 
			
		||||
  original_gmtime_r(timep, result);
 | 
			
		||||
  // While the camera is moving, the AI process is disabled by returning a day of the week that does not exist when motion is detected.
 | 
			
		||||
  struct timeval tv;
 | 
			
		||||
  gettimeofday(&tv, NULL);
 | 
			
		||||
  timersub(&tv, &MotorLastMovedTime, &tv);
 | 
			
		||||
  if(MotorFd || !tv.tv_sec) result->tm_wday = 8;
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,294 +0,0 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
extern int IMP_AI_DisableHpf();
 | 
			
		||||
extern int IMP_AI_DisableAgc();
 | 
			
		||||
extern int IMP_AI_DisableNs();
 | 
			
		||||
extern int IMP_AI_DisableAec();
 | 
			
		||||
extern int IMP_AI_EnableHpf();
 | 
			
		||||
extern int IMP_AI_EnableAgc();
 | 
			
		||||
extern int IMP_AI_EnableNs();
 | 
			
		||||
extern int IMP_AI_EnableAec();
 | 
			
		||||
extern int IMP_AI_SetVol();
 | 
			
		||||
extern int IMP_AI_SetGain();
 | 
			
		||||
extern int IMP_AI_SetAlcGain();
 | 
			
		||||
 | 
			
		||||
extern int IMP_AO_SetVol();
 | 
			
		||||
extern int IMP_AO_SetGain();
 | 
			
		||||
 | 
			
		||||
extern void set_video_max_fps();
 | 
			
		||||
extern void set_video_frame_rate();
 | 
			
		||||
extern void paracfg_set_user_config_item();
 | 
			
		||||
extern void set_fs_chn_config_fps();
 | 
			
		||||
 | 
			
		||||
extern void local_sdk_video_init();
 | 
			
		||||
extern void local_sdk_video_set_fps();
 | 
			
		||||
extern void local_sdk_video_set_gop();
 | 
			
		||||
 | 
			
		||||
extern void IMP_ISP_EnableTuning();
 | 
			
		||||
extern void IMP_ISP_Tuning_SetSensorFPS();
 | 
			
		||||
 | 
			
		||||
extern int IMP_ISP_Tuning_SetHVFLIP();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetContrast();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetBrightness();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetSaturation();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetSharpness();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetAeComp();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetAe_IT_MAX();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetDPC_Strength();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetDRC_Strength();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetHiLightDepress();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetTemperStrength();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetSinterStrength();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetMaxAgain();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetMaxDgain();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetBacklightComp();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetDPStrength();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetISPHflip();
 | 
			
		||||
extern int IMP_ISP_Tuning_SetISPVflip();
 | 
			
		||||
 | 
			
		||||
extern void CommandResponse(int fd, const char *res);
 | 
			
		||||
 | 
			
		||||
const char *productv2="/driver/sensor_jxf23.ko";
 | 
			
		||||
 | 
			
		||||
char *imp_Control(int fd, char *tokenPtr) {
 | 
			
		||||
 | 
			
		||||
//Audio
 | 
			
		||||
int devID = 1;
 | 
			
		||||
int chnID = 0;
 | 
			
		||||
int AO_devID = 0;
 | 
			
		||||
int AO_chnID = 0;
 | 
			
		||||
int ai_vol;
 | 
			
		||||
int ai_gain;
 | 
			
		||||
int alc_gain;
 | 
			
		||||
int ao_gain;
 | 
			
		||||
int ao_vol;
 | 
			
		||||
 | 
			
		||||
//Video
 | 
			
		||||
int fps_val;
 | 
			
		||||
int con_val;
 | 
			
		||||
int bright_val;
 | 
			
		||||
int sharp_val;
 | 
			
		||||
int satur_val;
 | 
			
		||||
int aecomp_val;
 | 
			
		||||
int aeitmax_val;
 | 
			
		||||
int dpc_val;
 | 
			
		||||
int drc_val;
 | 
			
		||||
int depress_val;
 | 
			
		||||
int temper_val;
 | 
			
		||||
int sinter_val;
 | 
			
		||||
int bcomp_val;
 | 
			
		||||
int again_val;
 | 
			
		||||
int dgain_val;
 | 
			
		||||
int dps_val;
 | 
			
		||||
 | 
			
		||||
//FPS
 | 
			
		||||
int encChn = 0;
 | 
			
		||||
int encChn1 = 1;
 | 
			
		||||
int fps_den = 1;
 | 
			
		||||
 | 
			
		||||
  char *p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
  if(!p) return "Please refer to the documentation for valid imp_control commands.";
 | 
			
		||||
  if(!strcmp(p, "agc_off")) {
 | 
			
		||||
   IMP_AI_DisableAgc();
 | 
			
		||||
  } else if(!strcmp(p, "agc_on")) {
 | 
			
		||||
   IMP_AI_EnableAgc();
 | 
			
		||||
  } else if(!strcmp(p, "hpf_off")) {
 | 
			
		||||
   IMP_AI_DisableHpf();
 | 
			
		||||
  } else if(!strcmp(p, "hpf_on")) {
 | 
			
		||||
   IMP_AI_EnableHpf();
 | 
			
		||||
  } else if(!strcmp(p, "ns_off")) {
 | 
			
		||||
   IMP_AI_DisableNs();
 | 
			
		||||
  } else if(!strcmp(p, "ns_on")) {
 | 
			
		||||
   IMP_AI_EnableNs();
 | 
			
		||||
  } else if(!strcmp(p, "aec_off")) {
 | 
			
		||||
   IMP_AI_DisableAec(devID, chnID);
 | 
			
		||||
  } else if(!strcmp(p, "aec_on")) {
 | 
			
		||||
   IMP_AI_EnableAec();
 | 
			
		||||
  } else if(!strcmp(p, "ai_vol")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) ai_vol = atoi(p);
 | 
			
		||||
	IMP_AI_SetVol(devID,chnID,ai_vol);
 | 
			
		||||
  } else if(!strcmp(p, "ai_gain")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) ai_gain = atoi(p);
 | 
			
		||||
	IMP_AI_SetGain(devID,chnID,ai_gain);
 | 
			
		||||
  } else if(!strcmp(p, "alc_gain")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) alc_gain = atoi(p);
 | 
			
		||||
	IMP_AI_SetAlcGain(devID,chnID,alc_gain);
 | 
			
		||||
  } else if(!strcmp(p, "ao_gain")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) ao_gain = atoi(p);
 | 
			
		||||
	IMP_AO_SetGain(AO_devID,AO_chnID,ao_gain);
 | 
			
		||||
  } else if(!strcmp(p, "ao_vol")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) ao_vol = atoi(p);
 | 
			
		||||
	IMP_AO_SetVol(AO_devID,AO_chnID,ao_vol);
 | 
			
		||||
  } else if(!strcmp(p, "flip_mirror")) {
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	if( access( productv2, F_OK ) != -1 ) {
 | 
			
		||||
		IMP_ISP_Tuning_SetISPHflip(0);
 | 
			
		||||
		IMP_ISP_Tuning_SetISPVflip(0);
 | 
			
		||||
	} else {
 | 
			
		||||
		IMP_ISP_Tuning_SetHVFLIP(0);
 | 
			
		||||
	}
 | 
			
		||||
  } else if(!strcmp(p, "flip_vertical")) {
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
 	if( access( productv2, F_OK ) != -1 ) {
 | 
			
		||||
		IMP_ISP_Tuning_SetISPVflip(0);
 | 
			
		||||
	} else {
 | 
			
		||||
		IMP_ISP_Tuning_SetHVFLIP(1);
 | 
			
		||||
	}
 | 
			
		||||
  } else if(!strcmp(p, "flip_horizontal")) {
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	if( access( productv2, F_OK ) != -1 ) {
 | 
			
		||||
		IMP_ISP_Tuning_SetISPHflip(0);
 | 
			
		||||
	} else {
 | 
			
		||||
		IMP_ISP_Tuning_SetHVFLIP(2);
 | 
			
		||||
	}
 | 
			
		||||
  } else if(!strcmp(p, "flip_normal")) {
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	if( access( productv2, F_OK ) != -1 ) {
 | 
			
		||||
		IMP_ISP_Tuning_SetISPHflip(1);
 | 
			
		||||
		IMP_ISP_Tuning_SetISPVflip(1);
 | 
			
		||||
	} else {
 | 
			
		||||
		IMP_ISP_Tuning_SetHVFLIP(3);
 | 
			
		||||
	}
 | 
			
		||||
  } else if(!strcmp(p, "fps_set")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) fps_val = atoi(p);
 | 
			
		||||
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	IMP_ISP_Tuning_SetSensorFPS(fps_val, fps_den);
 | 
			
		||||
 | 
			
		||||
	//encoder framerate failed
 | 
			
		||||
//	paracfg_set_user_config_item(5,fps_val);
 | 
			
		||||
 | 
			
		||||
//	set_fs_chn_config_fps(encChn, fps_val);
 | 
			
		||||
//	set_fs_chn_config_fps(encChn1, fps_val);
 | 
			
		||||
 | 
			
		||||
//	set_video_max_fps(fps_val);
 | 
			
		||||
//	local_sdk_video_set_fps(fps_val);
 | 
			
		||||
 | 
			
		||||
//	local_sdk_video_set_gop(encChn, fps_val);
 | 
			
		||||
 | 
			
		||||
//	local_sdk_video_init(fps_val);
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_contrast")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) con_val = atoi(p);
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	IMP_ISP_Tuning_SetContrast(con_val);
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_brightness")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) bright_val = atoi(p);
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	IMP_ISP_Tuning_SetBrightness(bright_val);
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_sharpness")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) sharp_val = atoi(p);
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	IMP_ISP_Tuning_SetSharpness(sharp_val);
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_saturation")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) satur_val = atoi(p);
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	IMP_ISP_Tuning_SetSaturation(satur_val);
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_aecomp")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) aecomp_val = atoi(p);
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	IMP_ISP_Tuning_SetAeComp(aecomp_val);
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_aeitmax")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) aeitmax_val = atoi(p);
 | 
			
		||||
	if( access( productv2, F_OK ) != -1 ) {
 | 
			
		||||
		return "not supported on v2";
 | 
			
		||||
	} else {
 | 
			
		||||
		IMP_ISP_EnableTuning();
 | 
			
		||||
		IMP_ISP_Tuning_SetAe_IT_MAX(aeitmax_val);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_dpc_strength")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) dpc_val = atoi(p);
 | 
			
		||||
	if( access( productv2, F_OK ) != -1 ) {
 | 
			
		||||
		return "not supported on v2";
 | 
			
		||||
	} else {
 | 
			
		||||
		IMP_ISP_EnableTuning();
 | 
			
		||||
		IMP_ISP_Tuning_SetDPC_Strength(dpc_val);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_drc_strength")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) drc_val = atoi(p);
 | 
			
		||||
	if( access( productv2, F_OK ) != -1 ) {
 | 
			
		||||
		return "not supported on v2";
 | 
			
		||||
	} else {
 | 
			
		||||
		IMP_ISP_EnableTuning();
 | 
			
		||||
		IMP_ISP_Tuning_SetDRC_Strength(drc_val);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_hilightdepress")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) depress_val = atoi(p);
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	IMP_ISP_Tuning_SetHiLightDepress(depress_val);
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_temper")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) temper_val = atoi(p);
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	IMP_ISP_Tuning_SetTemperStrength(temper_val);
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_sinter")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) sinter_val = atoi(p);
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	IMP_ISP_Tuning_SetSinterStrength(sinter_val);
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_dgain")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) dgain_val = atoi(p);
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	IMP_ISP_Tuning_SetMaxDgain(dgain_val);
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_again")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) again_val = atoi(p);
 | 
			
		||||
	IMP_ISP_EnableTuning();
 | 
			
		||||
	IMP_ISP_Tuning_SetMaxAgain(again_val);
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_backlightcomp")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) bcomp_val = atoi(p);
 | 
			
		||||
	if( access( productv2, F_OK ) != -1 ) {
 | 
			
		||||
		return "not supported on v2";
 | 
			
		||||
	} else {
 | 
			
		||||
		IMP_ISP_EnableTuning();
 | 
			
		||||
		IMP_ISP_Tuning_SetBacklightComp(bcomp_val);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
  } else if(!strcmp(p, "tune_dps")) {
 | 
			
		||||
        p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
        if(p) dps_val = atoi(p);
 | 
			
		||||
	if( access( productv2, F_OK ) != -1 ) {
 | 
			
		||||
		IMP_ISP_EnableTuning();
 | 
			
		||||
		IMP_ISP_Tuning_SetDPStrength(dps_val);
 | 
			
		||||
	} else {
 | 
			
		||||
		return "not supported on v3";
 | 
			
		||||
	}
 | 
			
		||||
} else {
 | 
			
		||||
    return "error";
 | 
			
		||||
  }
 | 
			
		||||
  return "ok";
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
extern int local_sdk_close_night_light();
 | 
			
		||||
extern int local_sdk_open_night_light();
 | 
			
		||||
extern int local_sdk_auto_night_light();
 | 
			
		||||
extern void CommandResponse(int fd, const char *res);
 | 
			
		||||
 | 
			
		||||
char *IrLed(int fd, char *tokenPtr) {
 | 
			
		||||
 | 
			
		||||
  char *p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
  if(!p) return "error";
 | 
			
		||||
  if(!strcmp(p, "on")) {
 | 
			
		||||
    local_sdk_open_night_light();
 | 
			
		||||
  } else if(!strcmp(p, "off")) {
 | 
			
		||||
    local_sdk_close_night_light();
 | 
			
		||||
  } else if(!strcmp(p, "auto")) {
 | 
			
		||||
    local_sdk_auto_night_light();
 | 
			
		||||
  } else {
 | 
			
		||||
    return "error";
 | 
			
		||||
  }
 | 
			
		||||
  return "ok";
 | 
			
		||||
}
 | 
			
		||||
@@ -1,118 +0,0 @@
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
struct channelConfigSt {
 | 
			
		||||
  uint dummy[4];
 | 
			
		||||
  int state;
 | 
			
		||||
  int encoder;
 | 
			
		||||
};
 | 
			
		||||
extern struct channelConfigSt *get_enc_chn_config(int ch);
 | 
			
		||||
extern int get_video_run_state(int ch);
 | 
			
		||||
extern void video_param_set_mutex_lock();
 | 
			
		||||
extern int IMP_Encoder_StartRecvPic(int ch);
 | 
			
		||||
extern int IMP_Encoder_PollingStream(int ch, int timeoutMSec);
 | 
			
		||||
extern int IMP_Encoder_GetStream(int ch, uint *stream, int);
 | 
			
		||||
extern int IMP_Encoder_ReleaseStream(int ch, int *stream);
 | 
			
		||||
extern int IMP_Encoder_StopRecvPic(int ch);
 | 
			
		||||
extern int save_jpeg(int fd, int *stream);
 | 
			
		||||
extern void video_param_set_mutex_unlock();
 | 
			
		||||
extern void CommandResponse(int fd, const char *res);
 | 
			
		||||
 | 
			
		||||
static const char *HttpResHeader = "Cache-Control: no-cache\nContent-Type: image/jpeg\n\n";
 | 
			
		||||
static const char *HttpErrorHeader = "Cache-Control: no-cache\nStatus: 503\n\n";
 | 
			
		||||
static pthread_mutex_t JpegDataMutex = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
static int JpegCaptureFd = -1;
 | 
			
		||||
 | 
			
		||||
char *JpegCapture(int fd, char *tokenPtr) {
 | 
			
		||||
 | 
			
		||||
  if(JpegCaptureFd >= 0) {
 | 
			
		||||
    fprintf(stderr, "[command] jpeg capture error %d %d\n", JpegCaptureFd, fd);
 | 
			
		||||
    write(fd, HttpErrorHeader, strlen(HttpErrorHeader));
 | 
			
		||||
    CommandResponse(fd, "error : jpeg capture error");
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  JpegCaptureFd = fd;
 | 
			
		||||
  pthread_mutex_unlock(&JpegDataMutex);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int GetJpegData(int fd) {
 | 
			
		||||
 | 
			
		||||
  struct channelConfigSt *chConfig = get_enc_chn_config(0);
 | 
			
		||||
  if (!chConfig->state) {
 | 
			
		||||
    fprintf(stderr, "[command] jpeg err: ch0 is not enable jpeg!\n");
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
  int state = get_video_run_state(0);
 | 
			
		||||
  if (state < 5) {
 | 
			
		||||
    fprintf(stderr, "[command] jpeg err: U should call 'video_run' before this func\n");
 | 
			
		||||
    return -1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  video_param_set_mutex_lock(1);
 | 
			
		||||
  int encoder = chConfig->encoder;
 | 
			
		||||
  int ret = 0;
 | 
			
		||||
 | 
			
		||||
  if(IMP_Encoder_StartRecvPic(encoder) < 0) {
 | 
			
		||||
    fprintf(stderr, "[command] jpeg err: IMP_Encoder_StartRecvPic(%d) failed\n", encoder);
 | 
			
		||||
    ret = -1;
 | 
			
		||||
    goto error1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if(IMP_Encoder_PollingStream(encoder, 2000) < 0) {
 | 
			
		||||
    fprintf(stderr, "[command] jpeg err: Polling stream(chn%d) timeout\n", encoder);
 | 
			
		||||
    ret = -1;
 | 
			
		||||
    goto error2;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  uint stream[17];
 | 
			
		||||
  memset(stream, 0, 60);
 | 
			
		||||
  if(IMP_Encoder_GetStream(encoder, stream, 1) < 0) {
 | 
			
		||||
    fprintf(stderr, "[command] jpeg err: IMP_Encoder_GetStream(chn%d) failed\n", encoder);
 | 
			
		||||
    ret = -1;
 | 
			
		||||
    goto error2;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  write(JpegCaptureFd, HttpResHeader, strlen(HttpResHeader));
 | 
			
		||||
  if(save_jpeg(fd, stream) < 0) {
 | 
			
		||||
    fprintf(stderr, "[command] jpeg err: save_jpeg(%d) failed\n", fd);
 | 
			
		||||
    ret = -2;
 | 
			
		||||
  }
 | 
			
		||||
  IMP_Encoder_ReleaseStream(encoder, stream);
 | 
			
		||||
 | 
			
		||||
error2:
 | 
			
		||||
  if(IMP_Encoder_StopRecvPic(encoder) < 0) {
 | 
			
		||||
    fprintf(stderr, "[command] jpeg err: IMP_Encoder_StopRecvPic(chn%d) failed\n", encoder);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
error1:
 | 
			
		||||
  video_param_set_mutex_unlock(1);
 | 
			
		||||
  if(ret == -1) write(JpegCaptureFd, HttpErrorHeader, strlen(HttpErrorHeader));
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *JpegCaptureThread() {
 | 
			
		||||
 | 
			
		||||
  while(1) {
 | 
			
		||||
    pthread_mutex_lock(&JpegDataMutex);
 | 
			
		||||
    if(JpegCaptureFd >= 0) {
 | 
			
		||||
      int res = GetJpegData(JpegCaptureFd);
 | 
			
		||||
      CommandResponse(JpegCaptureFd, res >= 0 ? "" : "error : buffer size error");
 | 
			
		||||
    }
 | 
			
		||||
    JpegCaptureFd = -1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) JpegInit(void) {
 | 
			
		||||
 | 
			
		||||
  pthread_mutex_lock(&JpegDataMutex);
 | 
			
		||||
  pthread_t thread;
 | 
			
		||||
  if(pthread_create(&thread, NULL, JpegCaptureThread, NULL)) {
 | 
			
		||||
    fprintf(stderr, "pthread_create error\n");
 | 
			
		||||
    pthread_mutex_unlock(&JpegDataMutex);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							@@ -1,7 +0,0 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
// disable mmc format
 | 
			
		||||
int local_sdk_device_mmc_format() {
 | 
			
		||||
  printf("skip local_sdk_device_mmc_format\n");
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,68 +0,0 @@
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
 | 
			
		||||
extern int local_sdk_motor_get_position(float *step,float *angle);
 | 
			
		||||
extern int local_sdk_motor_move_abs_angle(float pan, float tilt, int speed, void (*done)(float a, float b), void (*canceled)(void), int mode);
 | 
			
		||||
extern void CommandResponse(int fd, const char *res);
 | 
			
		||||
 | 
			
		||||
int MotorFd = 0;
 | 
			
		||||
struct timeval MotorLastMovedTime = { 0, 0 };
 | 
			
		||||
 | 
			
		||||
static void motor_move_done(float pan, float tilt) {
 | 
			
		||||
 | 
			
		||||
  if(MotorFd) {
 | 
			
		||||
    static char motorResBuf[256];
 | 
			
		||||
    sprintf(motorResBuf, "%f %f\n", pan, tilt);
 | 
			
		||||
    CommandResponse(MotorFd, motorResBuf);
 | 
			
		||||
  }
 | 
			
		||||
  MotorFd = 0;
 | 
			
		||||
  struct timeval tv;
 | 
			
		||||
  gettimeofday(&MotorLastMovedTime, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void motor_move_canceled() {
 | 
			
		||||
 | 
			
		||||
  if(MotorFd) CommandResponse(MotorFd, "error");
 | 
			
		||||
  MotorFd = 0;
 | 
			
		||||
  gettimeofday(&MotorLastMovedTime, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *MotorMove(int fd, char *tokenPtr) {
 | 
			
		||||
 | 
			
		||||
  char *p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
  if(!p) {
 | 
			
		||||
    float pan; // 0-355
 | 
			
		||||
    float tilt; // 0-180
 | 
			
		||||
    int ret = local_sdk_motor_get_position(&pan, &tilt);
 | 
			
		||||
    static char motorResBuf[256];
 | 
			
		||||
    if(!ret) {
 | 
			
		||||
      sprintf(motorResBuf, "%f %f\n", pan, tilt);
 | 
			
		||||
    } else {
 | 
			
		||||
      sprintf(motorResBuf, "- -\n");
 | 
			
		||||
    }
 | 
			
		||||
    return motorResBuf;
 | 
			
		||||
  }
 | 
			
		||||
  float pan = atof(p); // 0-355
 | 
			
		||||
  if((pan < 0.0) || (pan > 355.0)) return "error";
 | 
			
		||||
 | 
			
		||||
  p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
  if(!p) return "error";
 | 
			
		||||
  float tilt = atof(p); // 0-180
 | 
			
		||||
  if((tilt < 0.0) || (tilt > 180.0)) return "error";
 | 
			
		||||
 | 
			
		||||
  p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
  int pri = 2; // 0: high - 3: low
 | 
			
		||||
  if(p) pri = atoi(p);
 | 
			
		||||
  if(pri < 0) pri = 0;
 | 
			
		||||
  if(pri > 3) pri = 3;
 | 
			
		||||
 | 
			
		||||
  if(MotorFd) return "error";
 | 
			
		||||
  MotorFd = fd;
 | 
			
		||||
 | 
			
		||||
  int speed = 9;
 | 
			
		||||
  int res = local_sdk_motor_move_abs_angle(pan, tilt, speed, &motor_move_done, &motor_move_canceled, pri);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,70 +0,0 @@
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
static int (*original_mp4write_start_handler)(void *handler, char *file, void *config);
 | 
			
		||||
 | 
			
		||||
static int mp4WriteEnable = 0;
 | 
			
		||||
 | 
			
		||||
char *mp4Write(int fd, char *tokenPtr) {
 | 
			
		||||
 | 
			
		||||
  char *p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
  if(!p) return mp4WriteEnable ? "on" : "off";
 | 
			
		||||
  if(!strcmp(p, "on")) {
 | 
			
		||||
    mp4WriteEnable = 1;
 | 
			
		||||
    fprintf(stderr, "[command] mp4write on\n", p);
 | 
			
		||||
    return "ok";
 | 
			
		||||
  }
 | 
			
		||||
  if(!strcmp(p, "off")) {
 | 
			
		||||
    mp4WriteEnable = 0;
 | 
			
		||||
    fprintf(stderr, "[command] mp4write off\n", p);
 | 
			
		||||
    return "ok";
 | 
			
		||||
  }
 | 
			
		||||
  return "error in mp4write.c";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int mp4write_start_handler(void *handler, char *file, void *config, char *tokenPtr) {
 | 
			
		||||
 | 
			
		||||
if(mp4WriteEnable) {
 | 
			
		||||
 | 
			
		||||
  const char* folder;
 | 
			
		||||
    folder = "/media/mmc/record/tmp";
 | 
			
		||||
    struct stat sb;
 | 
			
		||||
 | 
			
		||||
   printf("[command] mp4write.c: checking for temporary record directory\n");
 | 
			
		||||
 | 
			
		||||
    if (stat(folder, &sb) == 0 && S_ISDIR(sb.st_mode)) {
 | 
			
		||||
    printf("[command] mp4write.c: temporary directory exists.\n");
 | 
			
		||||
    } else {
 | 
			
		||||
      printf("[command] mp4write.c: directory missing, creating directory\n");
 | 
			
		||||
      mkdir("/media/mmc/record/tmp", 0700);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  printf("mp4write.c: filename: %s\n", file);
 | 
			
		||||
 | 
			
		||||
  if(!strncmp(file, "/tmp/alarm_", 11)) {
 | 
			
		||||
  printf("mp4write.c: alarm, skipping\n", file);
 | 
			
		||||
  return (original_mp4write_start_handler)(handler, file, config);
 | 
			
		||||
  } else if(!strncmp(file, "/tmp/", 5)) {
 | 
			
		||||
    char buf[64];
 | 
			
		||||
    strncpy(buf, file + 5, 30);
 | 
			
		||||
    strcpy(file, "/media/mmc/record/tmp/");
 | 
			
		||||
    strcat(file, buf);
 | 
			
		||||
   }
 | 
			
		||||
 }
 | 
			
		||||
 | 
			
		||||
  return (original_mp4write_start_handler)(handler, file, config);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) mp4write_init(void) {
 | 
			
		||||
 | 
			
		||||
  original_mp4write_start_handler = dlsym(dlopen("/system/lib/libmp4rw.so", RTLD_LAZY), "mp4write_start_handler");
 | 
			
		||||
}
 | 
			
		||||
@@ -1,45 +0,0 @@
 | 
			
		||||
#define _GNU_SOURCE
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
static uint32_t (*real_local_sdk_video_set_fps)(int encChn);
 | 
			
		||||
 | 
			
		||||
int local_sdk_video_set_fps(int encChn) {
 | 
			
		||||
 | 
			
		||||
        fprintf(stderr, "[command] [night_drop.c] local_sdk_video_set_fps called with fps value: %d\n", encChn);
 | 
			
		||||
 | 
			
		||||
        const char *nd_enable="/opt/wz_mini/tmp/.nd";
 | 
			
		||||
        const char *product_T31="/opt/wz_mini/tmp/.T31";
 | 
			
		||||
        const char *product_T20="/opt/wz_mini/tmp/.T20";
 | 
			
		||||
 | 
			
		||||
        if( access( nd_enable, F_OK ) != -1 ) {
 | 
			
		||||
                printf("[command] [night_drop.c] Night Drop Enabled\n");
 | 
			
		||||
        if( encChn == 15 && access( product_T31, F_OK ) != -1 ) {
 | 
			
		||||
                printf("[command] [night_drop.c] T31 detected\n");
 | 
			
		||||
                fprintf(stderr, "[command] [night_drop.c] Night Time Requested FPS Drop Value: %d\n", encChn);
 | 
			
		||||
                printf("[command] [night_drop.c] Night FPS Drop Stopped\n");
 | 
			
		||||
        } else if ( encChn >= 15 && access( product_T20, F_OK ) != -1 ) {
 | 
			
		||||
                printf("[command] [night_drop.c] T20 detected\n");
 | 
			
		||||
                fprintf(stderr, "[command] [night_drop.c] Night Time Requested FPS Drop Value: %d\n", encChn);
 | 
			
		||||
                printf("[command] [night_drop.c] Night FPS Drop Stopped\n");
 | 
			
		||||
        } else {
 | 
			
		||||
                fprintf(stderr, "[command] [night_drop.c] Requested FPS Value: %d\n", encChn);
 | 
			
		||||
                fprintf(stderr, "[command] [night_drop.c] Calling local_sdk_video_set_fps to: %d\n", encChn);
 | 
			
		||||
                real_local_sdk_video_set_fps(encChn);
 | 
			
		||||
        }
 | 
			
		||||
	//If nd is disabled, pass all requests along
 | 
			
		||||
	} else {
 | 
			
		||||
	        printf("[command] [night_drop.c] Night Drop not enabled\n");
 | 
			
		||||
                fprintf(stderr, "[command] [night_drop.c] Requested FPS Value: %d\n", encChn);
 | 
			
		||||
                fprintf(stderr, "[command] [night_drop.c] Calling local_sdk_video_set_fps to: %d\n", encChn);
 | 
			
		||||
                real_local_sdk_video_set_fps(encChn);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) night_drop_init(void) {
 | 
			
		||||
  real_local_sdk_video_set_fps = dlsym(dlopen("/system/lib/liblocalsdk.so", RTLD_LAZY), "local_sdk_video_set_fps");
 | 
			
		||||
}
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
 | 
			
		||||
static DIR * (*original_opendir)(const char *pathname);
 | 
			
		||||
static const char *HookPath = "/media/mmc/time_lapse/time_Task_";
 | 
			
		||||
static const char *MediaPath = "/media/mmc/";
 | 
			
		||||
char TimeLapsePath[256];
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) opendir_hook_init(void) {
 | 
			
		||||
 | 
			
		||||
  original_opendir = dlsym(dlopen ("/lib/libc.so.0", RTLD_LAZY), "opendir");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DIR *opendir(const char *pathname) {
 | 
			
		||||
 | 
			
		||||
  if(!strncmp(pathname, HookPath, strlen(HookPath))) {
 | 
			
		||||
    strncpy(TimeLapsePath, pathname + strlen(MediaPath), 255);
 | 
			
		||||
    printf("[webhook] time_lapse_event %s\n", TimeLapsePath);
 | 
			
		||||
  }
 | 
			
		||||
  return original_opendir(pathname);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
static int (*original_remove)(const char *pathname);
 | 
			
		||||
static const char *HookPath = "/media/mmc/time_lapse/.setup";
 | 
			
		||||
extern char TimeLapsePath[256];
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) remove_hook_init(void) {
 | 
			
		||||
 | 
			
		||||
  original_remove = dlsym(dlopen ("/lib/libc.so.0", RTLD_LAZY), "remove");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int remove(const char *pathname) {
 | 
			
		||||
 | 
			
		||||
  if(!strncmp(pathname, HookPath, strlen(HookPath))) printf("[webhook] time_lapse_finish %s\n", TimeLapsePath);
 | 
			
		||||
  return original_remove(pathname);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) setStdoutLineBuffer(void) {
 | 
			
		||||
  setvbuf(stdout, NULL, _IOLBF, 0);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,211 +0,0 @@
 | 
			
		||||
#define _GNU_SOURCE
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <linux/videodev2.h>
 | 
			
		||||
#include <sys/ioctl.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
 | 
			
		||||
struct frames_st {
 | 
			
		||||
  void *buf;
 | 
			
		||||
  size_t length;
 | 
			
		||||
};
 | 
			
		||||
typedef int (* framecb)(struct frames_st *);
 | 
			
		||||
 | 
			
		||||
static int (*real_local_sdk_video_set_encode_frame_callback)(int ch, void *callback);
 | 
			
		||||
static void *video_encode_cb = NULL;
 | 
			
		||||
static void *video_encode_cb1 = NULL;
 | 
			
		||||
static int VideoCaptureEnable = 0;
 | 
			
		||||
static int VideoCaptureEnable1 = 0;
 | 
			
		||||
 | 
			
		||||
char *VideoCapture(int fd, char *tokenPtr) {
 | 
			
		||||
 | 
			
		||||
  char *p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
  if(!p) return VideoCaptureEnable ? "on" : "off";
 | 
			
		||||
  if(!strcmp(p, "on")) {
 | 
			
		||||
    VideoCaptureEnable = 1;
 | 
			
		||||
    fprintf(stderr, "[command] video capture ch0 on\n", p);
 | 
			
		||||
    return "ok";
 | 
			
		||||
  }
 | 
			
		||||
  if(!strcmp(p, "on1")) {
 | 
			
		||||
    VideoCaptureEnable1 = 1;
 | 
			
		||||
    fprintf(stderr, "[command] video capture ch1 on\n", p);
 | 
			
		||||
    return "ok";
 | 
			
		||||
  }
 | 
			
		||||
  if(!strcmp(p, "off")) {
 | 
			
		||||
    VideoCaptureEnable = 0;
 | 
			
		||||
    fprintf(stderr, "[command] video capture ch0 off\n", p);
 | 
			
		||||
    return "ok";
 | 
			
		||||
  }
 | 
			
		||||
  if(!strcmp(p, "off1")) {
 | 
			
		||||
    VideoCaptureEnable1 = 0;
 | 
			
		||||
    fprintf(stderr, "[command] video capture ch1 off\n", p);
 | 
			
		||||
    return "ok";
 | 
			
		||||
  }
 | 
			
		||||
  return "error";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static uint32_t video_encode_capture(struct frames_st *frames) {
 | 
			
		||||
 | 
			
		||||
  static int firstEntry = 0;
 | 
			
		||||
  static int v4l2Fd = -1;
 | 
			
		||||
 | 
			
		||||
//primary stream 0
 | 
			
		||||
  if(!firstEntry) {
 | 
			
		||||
    firstEntry++;
 | 
			
		||||
    int err;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    char *v4l2_device_path = "/dev/video0";
 | 
			
		||||
    //Check for this file, which should only exist on the V2 cameras
 | 
			
		||||
    const char *productv2="/driver/sensor_jxf23.ko";
 | 
			
		||||
 | 
			
		||||
    if( access( productv2, F_OK ) != -1 ) {
 | 
			
		||||
    v4l2_device_path = "/dev/video6";
 | 
			
		||||
    fprintf(stderr, "[command] v4l2_device_path = %s\n", v4l2_device_path);
 | 
			
		||||
    } else {
 | 
			
		||||
    v4l2_device_path = "/dev/video1";
 | 
			
		||||
    fprintf(stderr, "[command] v4l2_device_path = %s\n", v4l2_device_path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    const char *productf="/configs/.product_db3";
 | 
			
		||||
    fprintf(stderr,"Opening V4L2 device: %s \n", v4l2_device_path);
 | 
			
		||||
    v4l2Fd = open(v4l2_device_path, O_WRONLY, 0777);
 | 
			
		||||
    if(v4l2Fd < 0) fprintf(stderr,"Failed to open V4L2 device: %s\n", v4l2_device_path);
 | 
			
		||||
    struct v4l2_format vid_format;
 | 
			
		||||
    memset(&vid_format, 0, sizeof(vid_format));
 | 
			
		||||
    vid_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
 | 
			
		||||
 | 
			
		||||
    if( access( productf, F_OK ) == 0 ) {
 | 
			
		||||
                /* doorbell resolution */
 | 
			
		||||
                printf("[command] video product 1728x1296");
 | 
			
		||||
                vid_format.fmt.pix.width = 1728;
 | 
			
		||||
                vid_format.fmt.pix.height = 1296;
 | 
			
		||||
    } else {
 | 
			
		||||
                /* v3 and panv2 res */
 | 
			
		||||
                printf("[command] video product 1920x1080");
 | 
			
		||||
                vid_format.fmt.pix.width = 1920;
 | 
			
		||||
                vid_format.fmt.pix.height = 1080;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vid_format.fmt.pix.pixelformat = V4L2_PIX_FMT_H264;
 | 
			
		||||
    vid_format.fmt.pix.sizeimage = 0;
 | 
			
		||||
    vid_format.fmt.pix.field = V4L2_FIELD_NONE;
 | 
			
		||||
    vid_format.fmt.pix.bytesperline = 0;
 | 
			
		||||
    vid_format.fmt.pix.colorspace = V4L2_PIX_FMT_YUV420;
 | 
			
		||||
    err = ioctl(v4l2Fd, VIDIOC_S_FMT, &vid_format);
 | 
			
		||||
    if(err < 0) fprintf(stderr,"Unable to set V4L2 device video format: %d\n", err);
 | 
			
		||||
    err = ioctl(v4l2Fd, VIDIOC_STREAMON, &vid_format);
 | 
			
		||||
    if(err < 0) fprintf(stderr,"Unable to perform VIDIOC_STREAMON: %d\n", err);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if( (v4l2Fd >= 0) && VideoCaptureEnable) {
 | 
			
		||||
    uint32_t *buf = frames->buf;
 | 
			
		||||
    int size = write(v4l2Fd, frames->buf, frames->length);
 | 
			
		||||
    if(size != frames->length) fprintf(stderr,"Stream write error: %s\n", size);
 | 
			
		||||
  }
 | 
			
		||||
  return ((framecb)video_encode_cb)(frames);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//secondary stream 1
 | 
			
		||||
static uint32_t video_encode_capture1(struct frames_st *frames) {
 | 
			
		||||
 | 
			
		||||
  static int firstEntry = 0;
 | 
			
		||||
  static int v4l2Fd = -1;
 | 
			
		||||
 | 
			
		||||
  if(!firstEntry) {
 | 
			
		||||
    firstEntry++;
 | 
			
		||||
    int err;
 | 
			
		||||
 | 
			
		||||
    char *v4l2_device_path = "/dev/video0";
 | 
			
		||||
    //Check for this file, which should only exist on the V2 cameras
 | 
			
		||||
    const char *productv2="/driver/sensor_jxf23.ko";
 | 
			
		||||
 | 
			
		||||
    if( access( productv2, F_OK ) != -1 ) {
 | 
			
		||||
    v4l2_device_path = "/dev/video7";
 | 
			
		||||
    fprintf(stderr, "[command] v4l2_device_path = %s\n", v4l2_device_path);
 | 
			
		||||
    } else {
 | 
			
		||||
    v4l2_device_path = "/dev/video2";
 | 
			
		||||
    fprintf(stderr, "[command] v4l2_device_path = %s\n", v4l2_device_path);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const char *productf="/configs/.product_db3";
 | 
			
		||||
    fprintf(stderr,"Opening V4L2 device: %s \n", v4l2_device_path);
 | 
			
		||||
    v4l2Fd = open(v4l2_device_path, O_WRONLY, 0777);
 | 
			
		||||
    if(v4l2Fd < 0) fprintf(stderr,"Failed to open V4L2 device: %s\n", v4l2_device_path);
 | 
			
		||||
    struct v4l2_format vid_format;
 | 
			
		||||
    memset(&vid_format, 0, sizeof(vid_format));
 | 
			
		||||
    vid_format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
 | 
			
		||||
 | 
			
		||||
    if( access( productf, F_OK ) == 0 ) {
 | 
			
		||||
                /* doorbell resolution */
 | 
			
		||||
                printf("[command] video product 640x480");
 | 
			
		||||
                vid_format.fmt.pix.width = 640;
 | 
			
		||||
                vid_format.fmt.pix.height = 480;
 | 
			
		||||
    } else {
 | 
			
		||||
                /* v3 and panv2 res */
 | 
			
		||||
                printf("[command] video product 640x320");
 | 
			
		||||
                vid_format.fmt.pix.width = 640;
 | 
			
		||||
                vid_format.fmt.pix.height = 320;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    vid_format.fmt.pix.pixelformat = V4L2_PIX_FMT_H264;
 | 
			
		||||
    vid_format.fmt.pix.sizeimage = 0;
 | 
			
		||||
    vid_format.fmt.pix.field = V4L2_FIELD_NONE;
 | 
			
		||||
    vid_format.fmt.pix.bytesperline = 0;
 | 
			
		||||
    vid_format.fmt.pix.colorspace = V4L2_PIX_FMT_YUV420;
 | 
			
		||||
    err = ioctl(v4l2Fd, VIDIOC_S_FMT, &vid_format);
 | 
			
		||||
    if(err < 0) fprintf(stderr,"Unable to set V4L2 device video format: %d\n", err);
 | 
			
		||||
    err = ioctl(v4l2Fd, VIDIOC_STREAMON, &vid_format);
 | 
			
		||||
    if(err < 0) fprintf(stderr,"Unable to perform VIDIOC_STREAMON: %d\n", err);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if( (v4l2Fd >= 0) && VideoCaptureEnable) {
 | 
			
		||||
    uint32_t *buf = frames->buf;
 | 
			
		||||
    int size = write(v4l2Fd, frames->buf, frames->length);
 | 
			
		||||
    if(size != frames->length) fprintf(stderr,"Stream write error: %s\n", size);
 | 
			
		||||
  }
 | 
			
		||||
  return ((framecb)video_encode_cb1)(frames);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int local_sdk_video_set_encode_frame_callback(int ch, void *callback) {
 | 
			
		||||
 | 
			
		||||
  fprintf(stderr, "local_sdk_video_set_encode_frame_callback streamChId=%d, callback=0x%x\n", ch, callback);
 | 
			
		||||
  static int ch_count = 0;
 | 
			
		||||
 | 
			
		||||
/* two callbacks for video stream 0 are typically detected, unknown what the difference is between them, but if they are both hooked, the app breaks. grab just one of them. */
 | 
			
		||||
  //stream 0
 | 
			
		||||
  if( (ch == 0) && ch_count == 2) {
 | 
			
		||||
    video_encode_cb = callback;
 | 
			
		||||
    fprintf(stderr,"enc func injection save video_encode_cb=0x%x\n", video_encode_cb);
 | 
			
		||||
    callback = video_encode_capture;
 | 
			
		||||
  } else if( (ch == 0) && ch_count == 3) {
 | 
			
		||||
    video_encode_cb = callback;
 | 
			
		||||
    fprintf(stderr,"RTSP FIRMWARE enc func injection save video_encode_cb=0x%x\n", video_encode_cb);
 | 
			
		||||
    callback = video_encode_capture;
 | 
			
		||||
  }
 | 
			
		||||
    fprintf(stderr,"ch count is %x\n", ch_count);
 | 
			
		||||
 | 
			
		||||
  //stream 1
 | 
			
		||||
  if( (ch == 1) && ch_count == 1) {
 | 
			
		||||
    video_encode_cb1 = callback;
 | 
			
		||||
    fprintf(stderr,"enc func injection save video_encode_cb=0x%x\n", video_encode_cb1);
 | 
			
		||||
    callback = video_encode_capture1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    ch_count=ch_count+1;
 | 
			
		||||
 | 
			
		||||
  return real_local_sdk_video_set_encode_frame_callback(ch, callback);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) video_callback_init(void) {
 | 
			
		||||
 | 
			
		||||
  real_local_sdk_video_set_encode_frame_callback = dlsym(dlopen("/system/lib/liblocalsdk.so", RTLD_LAZY), "local_sdk_video_set_encode_frame_callback");
 | 
			
		||||
}
 | 
			
		||||
@@ -1,111 +0,0 @@
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <dlfcn.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <pthread.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
extern void CommandResponse(int fd, const char *res);
 | 
			
		||||
extern int local_sdk_motor_get_position(float *step,float *angle);
 | 
			
		||||
extern int MotorFd;
 | 
			
		||||
extern struct timeval MotorLastMovedTime;
 | 
			
		||||
 | 
			
		||||
struct RectInfoSt {
 | 
			
		||||
  int left;
 | 
			
		||||
  int right;
 | 
			
		||||
  int top;
 | 
			
		||||
  int bottom;
 | 
			
		||||
  int dummy1;
 | 
			
		||||
  int dummt2;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int (*original_local_sdk_video_osd_update_rect)(int ch, int display, struct RectInfoSt *rectInfo);
 | 
			
		||||
static int WaitMotionFd = -1;
 | 
			
		||||
static int Timeout = -1;
 | 
			
		||||
static pthread_mutex_t WaitMotionMutex = PTHREAD_MUTEX_INITIALIZER;
 | 
			
		||||
static pthread_cond_t WaitMotionCond = PTHREAD_COND_INITIALIZER;
 | 
			
		||||
 | 
			
		||||
char *WaitMotion(int fd, char *tokenPtr) {
 | 
			
		||||
 | 
			
		||||
  if(WaitMotionFd >= 0) {
 | 
			
		||||
    fprintf(stderr, "[command] wait motion error %d %d\n", WaitMotionFd, fd);
 | 
			
		||||
    return "error : wait motion error";
 | 
			
		||||
  }
 | 
			
		||||
  char *p = strtok_r(NULL, " \t\r\n", &tokenPtr);
 | 
			
		||||
  Timeout = p ? atoi(p) : 0;
 | 
			
		||||
  if(Timeout < 10) {
 | 
			
		||||
    fprintf(stderr, "[command] wait motion timeout error timeout = %d\n", Timeout);
 | 
			
		||||
    return "error : wait motion timeout value error";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  WaitMotionFd = fd;
 | 
			
		||||
  pthread_mutex_unlock(&WaitMotionMutex);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int local_sdk_video_osd_update_rect(int ch, int display, struct RectInfoSt *rectInfo) {
 | 
			
		||||
 | 
			
		||||
  if((WaitMotionFd >= 0) && (MotorFd <= 0) && !ch) {
 | 
			
		||||
    struct timeval tv;
 | 
			
		||||
    gettimeofday(&tv, NULL);
 | 
			
		||||
    timersub(&tv, &MotorLastMovedTime, &tv);
 | 
			
		||||
    if(tv.tv_sec || (tv.tv_usec >= 500000)) {
 | 
			
		||||
      if(display) {
 | 
			
		||||
        float pan; // 0-355
 | 
			
		||||
        float tilt; // 0-180
 | 
			
		||||
        int ret = local_sdk_motor_get_position(&pan, &tilt);
 | 
			
		||||
        static char waitMotionResBuf[256];
 | 
			
		||||
        if(!ret) {
 | 
			
		||||
          pan += (rectInfo->left + rectInfo->right - 320 * 2) * 85 / (2 * 640);
 | 
			
		||||
          if(pan < 0.0) pan = 0.0;
 | 
			
		||||
          if(pan > 355.0) pan = 355;
 | 
			
		||||
          tilt -= (rectInfo->top + rectInfo->bottom - 180 * 2) * 55 / (2 * 360);
 | 
			
		||||
          if(tilt < 45.0) tilt = 45.0;
 | 
			
		||||
          if(tilt > 180.0) tilt = 180.0;
 | 
			
		||||
          sprintf(waitMotionResBuf, "detect %d %d %d %d %d %d\n",
 | 
			
		||||
            rectInfo->left, rectInfo->right, rectInfo->top, rectInfo->bottom, lroundf(pan), lroundf(tilt));
 | 
			
		||||
        } else {
 | 
			
		||||
          sprintf(waitMotionResBuf, "detect %d %d %d %d - -\n",
 | 
			
		||||
            rectInfo->left, rectInfo->right, rectInfo->top, rectInfo->bottom);
 | 
			
		||||
        }
 | 
			
		||||
        CommandResponse(WaitMotionFd, waitMotionResBuf);
 | 
			
		||||
      } else {
 | 
			
		||||
        CommandResponse(WaitMotionFd, "clear\n");
 | 
			
		||||
      }
 | 
			
		||||
      pthread_cond_signal(&WaitMotionCond);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return original_local_sdk_video_osd_update_rect(ch, display, rectInfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void *WaitMotionThread() {
 | 
			
		||||
 | 
			
		||||
  while(1) {
 | 
			
		||||
    pthread_mutex_lock(&WaitMotionMutex);
 | 
			
		||||
    if(WaitMotionFd >= 0) {
 | 
			
		||||
      struct timeval now;
 | 
			
		||||
      struct timespec timeout;
 | 
			
		||||
      gettimeofday(&now, NULL);
 | 
			
		||||
      timeout.tv_sec = now.tv_sec + Timeout;
 | 
			
		||||
      timeout.tv_nsec = now.tv_usec * 1000;
 | 
			
		||||
      int ret = pthread_cond_timedwait(&WaitMotionCond, &WaitMotionMutex, &timeout);
 | 
			
		||||
      if(ret == ETIMEDOUT) CommandResponse(WaitMotionFd, "timeout\n");
 | 
			
		||||
    }
 | 
			
		||||
    WaitMotionFd = -1;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void __attribute ((constructor)) osd_rect_hook_init(void) {
 | 
			
		||||
 | 
			
		||||
  original_local_sdk_video_osd_update_rect = dlsym(dlopen ("/system/lib/liblocalsdk.so", RTLD_LAZY), "local_sdk_video_osd_update_rect");
 | 
			
		||||
 | 
			
		||||
  pthread_mutex_lock(&WaitMotionMutex);
 | 
			
		||||
  pthread_t thread;
 | 
			
		||||
  if(pthread_create(&thread, NULL, WaitMotionThread, NULL)) {
 | 
			
		||||
    fprintf(stderr, "pthread_create error\n");
 | 
			
		||||
    pthread_mutex_unlock(&WaitMotionMutex);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user