Explorar o código

* initial import

Lelik P. Korchagin %!s(int64=3) %!d(string=hai) anos
achega
3806c69e66
Modificáronse 7 ficheiros con 840 adicións e 0 borrados
  1. 6 0
      .gitignore
  2. 25 0
      Makefile
  3. 119 0
      fpvcopy.c
  4. 110 0
      fpvdump.c
  5. 98 0
      fpvextract.c
  6. 292 0
      fpvplay.c
  7. 190 0
      fpvstat.c

+ 6 - 0
.gitignore

@@ -0,0 +1,6 @@
+*.fpv
+*.rej
+*.orig
+*.o
+*~
+core

+ 25 - 0
Makefile

@@ -0,0 +1,25 @@
+LDFLAGS=-lrt -ggdb
+CPPFLAGS=-Wall -DGND -D_GNU_SOURCE -ggdb
+
+all:	fpvextract fpvplay fpvdump fpvcopy fpvstat
+
+%.o: %.c %.h
+	$(CC) -c -o $@ $< $(CPPFLAGS)
+
+fpvplay: 	fpvplay.o
+	$(CC) -o $@ $^ $(LDFLAGS)
+
+fpvextract: 	fpvextract.o
+	$(CC) -o $@ $^ $(LDFLAGS)
+
+fpvdump: 	fpvdump.o
+	$(CC) -o $@ $^ $(LDFLAGS)
+
+fpvcopy: 	fpvcopy.o
+	$(CC) -o $@ $^ $(LDFLAGS)
+
+fpvstat: 	fpvstat.o
+	$(CC) -o $@ $^ $(LDFLAGS)
+
+clean:
+	rm -f fpvextract fpvplay fpvdump fpvcopy *~ *.o

+ 119 - 0
fpvcopy.c

@@ -0,0 +1,119 @@
+# include <stdio.h>
+# include <stdint.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <errno.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <arpa/inet.h>
+# include <getopt.h>
+
+struct fpv
+{
+        uint32_t        		len;
+        uint8_t         		type;
+        uint32_t        		ms;
+        uint8_t         		pad[8];
+} __attribute__((packed));
+
+
+static const char short_options[] = "s:e:";
+static const struct option long_options[] =
+{
+        { "start",	required_argument,  	NULL, 's' },
+        { "end",   	required_argument,  	NULL, 'e' },
+        { 0, 		0, 			NULL,  0  }
+};
+
+static int opt_s = 0;
+static int opt_e = -1;
+
+size_t in(int fd, uint8_t *data, size_t len)
+{
+        int res = 0;
+
+        while (len > 0) {
+                size_t n = read(fd, data, len);
+                if (n > 0) {
+                        len -= n;
+                        data += n;
+                        res  += n;
+                } else {
+                        if (n < 0) {
+                                if (errno != EAGAIN) {
+                                        printf("read: %s\n", strerror(errno));
+                                } else {
+                                        continue;
+                                }
+                        }
+                        break;
+                }
+        }
+        return res;
+}
+
+int main(int argc, char *argv[])
+{
+        struct fpv fpv;
+        static uint8_t data[8 * 1024 * 1024];
+        int i;
+
+        for (;;) {
+                int c;
+
+                if ((c = getopt_long_only(argc, argv, short_options, long_options, &i)) == -1) {
+                        break;
+                }
+
+                switch (c) {
+                case 's':
+                        opt_s = atoi(optarg);
+                        break;
+
+                case 'e':
+                        opt_e = atoi(optarg);
+                        break;
+
+                case 0:
+                        break;
+
+                default:
+                        return 1;
+                }
+        }
+
+        if ((argc - optind) < 1) {
+                return 1;
+        }
+
+        for (i = 0; (optind + i) < argc; i++) {
+                int fd = open(argv[optind + i], O_RDONLY);
+
+                fprintf(stderr, "%s\n", argv[optind + i]);
+                if (fd >= 0) {
+                        while (1) {
+                                if (in(fd, (uint8_t*)&fpv, sizeof(fpv)) < 0) {
+                                        break;
+                                }
+
+                                if (in(fd, data, fpv.len) < 0) {
+                                        break;
+                                }
+
+                                if (opt_e > 0 && fpv.ms >= opt_e) {
+                                        break;
+                                }
+
+                                if (fpv.ms >= opt_s) {
+                                        fpv.ms -= opt_s;
+                                        write(fileno(stdout), &fpv, sizeof(fpv));
+                                        write(fileno(stdout), data, fpv.len);
+                                }
+                        }
+                        close(fd);
+                }
+        }
+        return 0;
+}

+ 110 - 0
fpvdump.c

@@ -0,0 +1,110 @@
+# include <stdio.h>
+# include <stdint.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <errno.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <arpa/inet.h>
+# include <getopt.h>
+
+struct fpv
+{
+        uint32_t        		len;
+        uint8_t         		type;
+        uint32_t        		ms;
+        uint8_t         		pad[8];
+} __attribute__((packed));
+
+
+static const char short_options[] = "s:e:";
+static const struct option long_options[] =
+{
+        { "start",	required_argument,  	NULL, 's' },
+        { "end",   	required_argument,  	NULL, 'e' },
+        { 0, 		0, 			NULL,  0  }
+};
+
+static int opt_s = 0;
+static int opt_e = 0;
+
+size_t in(int fd, uint8_t *data, size_t len)
+{
+        int res = 0;
+
+        while (len > 0) {
+                size_t n = read(fd, data, len);
+                if (n > 0) {
+                        len -= n;
+                        data += n;
+                        res  += n;
+                } else {
+                        if (n < 0) {
+                                if (errno != EAGAIN) {
+                                        printf("read: %s\n", strerror(errno));
+                                } else {
+                                        continue;
+                                }
+                        }
+                        break;
+                }
+        }
+        return res;
+}
+
+int main(int argc, char *argv[])
+{
+        struct fpv fpv;
+        static uint8_t data[8 * 1024 * 1024];
+        int i;
+
+        for (;;) {
+                int c;
+
+                if ((c = getopt_long_only(argc, argv, short_options, long_options, &i)) == -1) {
+                        break;
+                }
+
+                switch (c) {
+                case 's':
+                        opt_s = atoi(optarg);
+                        break;
+
+                case 'e':
+                        opt_e = atoi(optarg);
+                        break;
+
+                case 0:
+                        break;
+
+                default:
+                        return 1;
+                }
+        }
+
+        if ((argc - optind) < 1) {
+                return 1;
+        }
+
+        for (i = 0; (optind + i) < argc; i++) {
+                int fd = open(argv[optind + i], O_RDONLY);
+
+                if (fd >= 0) {
+                        while (1) {
+                                if (in(fd, (uint8_t*)&fpv, sizeof(fpv)) > 0) {
+                                        if (in(fd, data, fpv.len) > 0) {
+                                                if (fpv.ms >= opt_s) {
+                                                        printf("%1u %10u %10u\n", fpv.type, fpv.ms, fpv.len);
+                                                }
+                                        	continue;
+                                        }
+                                }
+                                break;
+                        }
+                        close(fd);
+                }
+        }
+        return 0;
+}

+ 98 - 0
fpvextract.c

@@ -0,0 +1,98 @@
+# include <stdio.h>
+# include <stdint.h>
+# include <unistd.h>
+# include <string.h>
+# include <errno.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <arpa/inet.h>
+
+struct fpv
+{
+        uint32_t        		len;
+        uint8_t         		type;
+        uint32_t        		ms;
+        uint8_t         		pad[8];
+} __attribute__((packed));
+
+size_t out(int fd, uint8_t *data, size_t len)
+{
+        int res = 0;
+
+        while (len > 0) {
+                size_t n;
+
+                if ((n = write(fd, data, len)) > 0) {
+                        len -= n;
+                        data += n;
+                        res  += n;
+                } else {
+                        if (errno != EAGAIN) {
+                                printf("write: %s\n", strerror(errno));
+                        } else {
+                                continue;
+                        }
+                        break;
+                }
+        }
+        return res;
+}
+
+size_t in(int fd, uint8_t *data, size_t len)
+{
+        int res = 0;
+
+        while (len > 0) {
+                size_t n = read(fd, data, len);
+                if (n > 0) {
+                        len -= n;
+                        data += n;
+                        res  += n;
+                } else {
+                        if (n < 0) {
+                                if (errno != EAGAIN) {
+                                        printf("read: %s\n", strerror(errno));
+                                } else {
+                                        continue;
+                                }
+                        }
+                        break;
+                }
+        }
+        return res;
+}
+
+int main(int argc, char *argv[])
+{
+        struct fpv fpv;
+        static uint8_t data[8 * 1024 * 1024];
+        int i;
+
+        for (i = 1; i < argc; i++) {
+                int fd = open(argv[i], O_RDONLY);
+
+                if (fd >= 0) {
+                        while (1) {
+                                if (in(fd, (uint8_t*)&fpv, sizeof(fpv)) > 0) {
+                                        if (in(fd, data, fpv.len) > 0) {
+                                                switch (fpv.type) {
+                                                case 0:
+                                                        out(fileno(stdout), data, fpv.len);
+                                                        break;
+
+                                                default:
+                                                        continue;
+                                                }
+                                        } else {
+                                                break;
+                                        }
+                                } else {
+                                        break;
+                                }
+                        }
+                        close(fd);
+                }
+        }
+        return 0;
+}

+ 292 - 0
fpvplay.c

@@ -0,0 +1,292 @@
+# include <stdio.h>
+# include <stdint.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <errno.h>
+# include <getopt.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <arpa/inet.h>
+
+struct fpv
+{
+        uint32_t        		len;
+        uint8_t         		type;
+        uint32_t        		ms;
+        uint8_t         		pad[8];
+} __attribute__((packed));
+
+size_t out(int fd, struct sockaddr_in *to, uint8_t *data, size_t len)
+{
+        int res = 0;
+
+        while (len > 0) {
+                size_t n = len;
+
+                if (n > 1400) {
+                        n = 1400;
+                }
+
+                if ((n = sendto(fd, data, n, 0, (struct sockaddr*)to, sizeof(struct sockaddr_in))) > 0) {
+                        len -= n;
+                        data += n;
+                        res  += n;
+                } else {
+                        if (errno != EAGAIN) {
+                                printf("write: %s\n", strerror(errno));
+                        } else {
+                                continue;
+                        }
+                        break;
+                }
+        }
+        return res;
+}
+
+enum
+{
+        NUT_CODED_SLICE_NON_IDR          =  1,  // Coded slice of a non-IDR picture
+        NUT_CODED_SLICE_IDR              =  5,  // Coded slice of an IDR picture
+        NUT_SPS                          =  7,  // Sequence parameter set
+        NUT_PPS                          =  8   // Picture parameter set
+};
+
+struct parameter_set
+{
+        uint8_t         data[256];
+        size_t          length;
+        int             found;
+};
+
+size_t out_v(int fd, struct sockaddr_in *to, uint8_t *data, int len)
+{
+        static struct parameter_set sps = { .data = { 0, }, .length = 0, .found = 0 };
+        static struct parameter_set pps = { .data = { 0, }, .length = 0, .found = 0 };
+        static struct parameter_set *ps = NULL;
+
+        static struct { uint8_t data[4];    int length; } marker = { .length = 0, .data = { 0, } };
+        struct        { uint8_t data[4096]; int length; } pkt    = { .length = 0 };
+        int p;
+
+        for (p = 0; p < len; p++) {
+                int c = data[p];
+
+                if (marker.length == 4) {
+                        if (memcmp(marker.data, "\x00\x00\x00\x01", 4) == 0) {
+                                switch (c & 0x1F) {
+                                case NUT_SPS:
+                                        memset(ps = &sps, 0, sizeof(sps));
+                                        sps.found = 1;
+                                        break;
+
+                                case NUT_PPS:
+                                        memset(ps = &pps, 0, sizeof(pps));
+                                        pps.found = 1;
+                                        break;
+
+                                case NUT_CODED_SLICE_NON_IDR:
+                                case NUT_CODED_SLICE_IDR:
+                                        if (sps.found == 0 && sps.length > 0) {
+                                                int i; for (i = 0; i < sps.length; i++) {
+                                                        if (pkt.length < sizeof(pkt.data)) {
+                                                                pkt.data[pkt.length++] = sps.data[i];
+                                                        }
+                                                }
+                                        }
+                                        sps.found = 0;
+
+                                        if (pps.found == 0 && pps.length > 0) {
+                                                int i; for (i = 0; i < pps.length; i++) {
+                                                        if (pkt.length < sizeof(pkt.data)) {
+                                                                pkt.data[pkt.length++] = pps.data[i];
+                                                        }
+                                                }
+                                        }
+                                        pps.found = 0;
+
+                                default:
+                                        ps = NULL;
+                                        break;
+                                }
+
+                                marker.data[0] = 0;
+                                marker.data[1] = 0;
+                                marker.data[2] = 0;
+                                marker.data[3] = 0;
+                                marker.length  = 0;
+                        } else {
+                                marker.data[0] = marker.data[1];
+                                marker.data[1] = marker.data[2];
+                                marker.data[2] = marker.data[3];
+                                marker.data[3] = c & 0xFF;
+                        }
+                } else {
+                        marker.data[marker.length++] = c & 0xFF;;
+                }
+
+                if (ps != NULL) {
+                        if (ps->length < sizeof(ps->data)) {
+                                ps->data[ps->length++] = c & 0xFF;
+                        } else {
+                                memset(ps, 0, sizeof(*ps));
+                                ps = NULL;
+                        }
+                }
+                if (pkt.length < sizeof(pkt.data)) {
+                        pkt.data[pkt.length++] = c & 0xFF;
+                }
+        }
+
+	return out(fd, to, pkt.data, pkt.length);
+}
+
+size_t in(int fd, uint8_t *data, size_t len)
+{
+        int res = 0;
+
+        while (len > 0) {
+                size_t n = read(fd, data, len);
+                if (n > 0) {
+                        len -= n;
+                        data += n;
+                        res  += n;
+                } else {
+                        if (n < 0) {
+                                if (errno != EAGAIN) {
+                                        printf("read: %s\n", strerror(errno));
+                                } else {
+                                        continue;
+                                }
+                        }
+                        break;
+                }
+        }
+        return res;
+}
+
+static const char short_options[] = "s:e:t:";
+static const struct option long_options[] =
+{
+        { "start",	required_argument,  	NULL, 's' },
+        { "end",   	required_argument,  	NULL, 'e' },
+        { "to",   	required_argument,  	NULL, 't' },
+        { 0, 		0, 			NULL,  0  }
+};
+
+static int    opt_s = -1;
+static int    opt_e = -1;
+static char  *opt_t = "127.255.255.255";
+
+int main(int argc, char *argv[])
+{
+        struct fpv 	fpv;
+        static uint8_t data[8 * 1024 * 1024];
+        int i;
+
+        for (;;) {
+                int c;
+
+                if ((c = getopt_long_only(argc, argv, short_options, long_options, &i)) == -1) {
+                        break;
+                }
+
+                switch (c) {
+                case 's':
+                        opt_s = atoi(optarg);
+                        break;
+
+                case 'e':
+                        opt_e = atoi(optarg);
+                        break;
+
+                case 't':
+                        opt_t = optarg;
+                        break;
+
+                case 0:
+                        break;
+
+                default:
+                        return 1;
+                }
+        }
+
+
+        struct sockaddr_in all;
+        int on = 1;
+        int udp;
+
+        memset(&all, 0, sizeof(all));
+        all.sin_family = AF_INET;
+        all.sin_addr.s_addr = inet_addr(opt_t);
+        all.sin_port = htons(0);
+
+        udp = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
+        setsockopt(udp, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));
+
+        if ((argc - optind) < 1) {
+                return 1;
+        }
+
+        for (i = 0; (optind + i) < argc; i++) {
+                int fd = open(argv[optind + i], O_RDONLY);
+                int ms = 0;
+
+                if (fd >= 0) {
+                        while (1) {
+                                if (in(fd, (uint8_t*)&fpv, sizeof(fpv)) > 0) {
+                                        int play = 1;
+
+                                        if (opt_s > 0 && fpv.ms < opt_s) {
+                                                play = 0;
+                                        }
+
+                                        if (opt_e > 0 && fpv.ms >= opt_e) {
+                                                break;
+                                        }
+
+                                        if (play) {
+                                                int sleep = fpv.ms - ms;
+                                                if (sleep > 0) {
+                                                        usleep(sleep * 1000);
+                                                }
+                                        }
+                                        ms = fpv.ms;
+
+                                        if (in(fd, data, fpv.len) > 0) {
+                                                if (!play) {
+                                                        continue;
+                                                }
+
+                                                switch (fpv.type) {
+                                                case 0:
+                                                        all.sin_port = htons(5000);
+                                                        break;
+
+                                                case 2:
+                                                        all.sin_port = htons(14550);
+                                                        break;
+
+                                                case 5:
+                                                        all.sin_port = htons(5003);
+                                                        break;
+
+                                                default:
+                                                        continue;
+                                                }
+
+                                        	out(udp, &all, data, fpv.len);
+                                        } else {
+                                                break;
+                                        }
+                                } else {
+                                        break;
+                                }
+                        }
+                        close(fd);
+                }
+        }
+        return 0;
+}

+ 190 - 0
fpvstat.c

@@ -0,0 +1,190 @@
+# include <stdio.h>
+# include <stdint.h>
+# include <stdlib.h>
+# include <unistd.h>
+# include <string.h>
+# include <errno.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <arpa/inet.h>
+# include <getopt.h>
+
+struct fpv
+{
+        uint32_t        		len;
+        uint8_t         		type;
+        uint32_t        		ms;
+        uint8_t         		pad[8];
+} __attribute__((packed));
+
+struct cpu
+{
+	uint8_t 			load;
+        uint8_t 			temp;
+}  					__attribute__((packed));
+
+struct air
+{
+        struct
+        {
+        	int8_t 			rssi;
+        	uint32_t 		lost;
+        } 				__attribute__((packed))	uplink;
+
+        struct
+        {
+        	int8_t 			rssi;
+        	uint32_t 		lost;
+        } 				__attribute__((packed))	rc;
+
+        struct cpu			cpu;
+        uint32_t 			blocks;
+        uint32_t 			skipped;
+        uint32_t 			failed;
+        long long 			time;
+        uint16_t 			bitrate;
+        uint16_t 			measured_bitrate;
+        uint8_t 			cts;
+        uint8_t 			undervoltage;
+} 					__attribute__((packed));
+
+struct gnd
+{
+        uint32_t 			broken;
+        uint32_t 			lost;
+        uint32_t 			skipped;
+        uint32_t 			received;
+        uint32_t 			real_bitrate;
+        uint32_t 			measured_bitrate;
+        uint32_t 			bitrate;
+        uint32_t 			uplink_lost;
+        uint32_t 			downlink_lost;
+        uint32_t 			unused[3];
+        int8_t 				air_rssi;
+        int8_t 				joystick;
+        struct
+        {
+                struct cpu              gnd;
+                struct cpu              air;
+        }                               __attribute__((packed)) cpu;
+        uint32_t 			nics;
+        struct
+        {
+
+                uint32_t 		packets;
+                int8_t 			rssi;
+                int8_t 			type;
+        }				__attribute__((packed)) nic[6];
+} __attribute__((packed));
+
+
+static const char short_options[] = "s:e:";
+static const struct option long_options[] =
+{
+        { "start",	required_argument,  	NULL, 's' },
+        { "end",   	required_argument,  	NULL, 'e' },
+        { 0, 		0, 			NULL,  0  }
+};
+
+static int opt_s = 0;
+static int opt_e = 0;
+
+size_t in(int fd, uint8_t *data, size_t len)
+{
+        int res = 0;
+
+        while (len > 0) {
+                size_t n = read(fd, data, len);
+                if (n > 0) {
+                        len -= n;
+                        data += n;
+                        res  += n;
+                } else {
+                        if (n < 0) {
+                                if (errno != EAGAIN) {
+                                        printf("read: %s\n", strerror(errno));
+                                } else {
+                                        continue;
+                                }
+                        }
+                        break;
+                }
+        }
+        return res;
+}
+
+int main(int argc, char *argv[])
+{
+        struct fpv fpv;
+        static uint8_t data[8 * 1024 * 1024];
+        int i;
+
+        for (;;) {
+                int c;
+
+                if ((c = getopt_long_only(argc, argv, short_options, long_options, &i)) == -1) {
+                        break;
+                }
+
+                switch (c) {
+                case 's':
+                        opt_s = atoi(optarg);
+                        break;
+
+                case 'e':
+                        opt_e = atoi(optarg);
+                        break;
+
+                case 0:
+                        break;
+
+                default:
+                        return 1;
+                }
+        }
+
+        if ((argc - optind) < 1) {
+                return 1;
+        }
+
+        for (i = 0; (optind + i) < argc; i++) {
+                int fd = open(argv[optind + i], O_RDONLY);
+
+                if (fd >= 0) {
+                        while (1) {
+                                if (in(fd, (uint8_t*)&fpv, sizeof(fpv)) > 0) {
+                                        if (in(fd, data, fpv.len) > 0) {
+                                                switch (fpv.type) {
+                                                case 5:
+                                                        {
+                                                                struct gnd *gnd = (struct gnd *)data;
+                                                                for (i = 0; i < gnd->nics; i++) {
+                                                                        printf(" %5d", gnd->nic[i].rssi);
+                                                                }
+                                                                printf(" %5d", gnd->lost);
+                                                                printf(" %5d", gnd->broken);
+                                                                printf(" %5d", gnd->air_rssi);
+                                                                printf(" %5d", gnd->uplink_lost);
+                                                                printf(" %5d", gnd->uplink_lost);
+                                                                printf(" %5d", gnd->cpu.air.load);
+                                                                printf(" %5d", gnd->cpu.air.temp);
+                                                                printf(" %5d", gnd->cpu.gnd.load);
+                                                                printf(" %5d", gnd->cpu.gnd.temp);
+                                                                printf("\n");
+                                                                continue;
+                                                        }
+                                                        break;
+
+                                                default:
+                                                        continue;
+                                                }
+                                        }
+                                }
+                                break;
+                        }
+                        close(fd);
+                }
+        }
+        return 0;
+}