-
Notifications
You must be signed in to change notification settings - Fork 1
/
sdvr.c
159 lines (132 loc) · 4.96 KB
/
sdvr.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <time.h>
#include "sdvr.h"
#include "pk.h"
char dvr_name[32];
char dvr_vdef[32];
void error(char *msg) {
perror(msg);
exit(0);
}
// This function only exists because read() sometimes returns less data than it
// should, even though there is more data in the socket.
size_t stable_read(int fd, void *buffer, size_t count) {
size_t read_so_far = 0;
while(read_so_far < count) {
int read_this_go = read(fd, buffer + read_so_far, count - read_so_far);
if(read_this_go < 0) return read_this_go;
read_so_far += read_this_go;
}
return read_so_far;
}
int main(int argc, char** argv) {
if(argc < 5) {
printf("usage: sdvr ip port username password\nport is usually 9000\n");
return 1;
}
fprintf(stderr, "%s version %s\n", NAME, VERSION);
struct hostent *dvr_host = gethostbyname(argv[1]);
if(dvr_host == NULL) error("no such host");
int dvr_port = atoi(argv[2]);
struct sockaddr_in dvr;
bzero(&dvr, sizeof(struct sockaddr_in));
dvr.sin_family = AF_INET;
// Copy the address
memcpy(&(dvr.sin_addr.s_addr), dvr_host->h_addr, dvr_host->h_length);
// Copy the port
dvr.sin_port = htons(dvr_port);
// Create the socket
int sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if(sock_fd < 0) error("failed to open socket");
// Connect the socket
if(connect(sock_fd, &dvr, sizeof(struct sockaddr_in)) < 0) error("failed to connect");
fprintf(stderr, "Socket connected.\n");
// Socket connected at this point, now;
// 1. Send auth packet
// 2. Receive initial response
// 3. (maybe send other packets)
// 4. Receive frames
// Create auth packet
struct pk_c_01_s *auth_packet = malloc(sizeof(struct pk_c_01_s));
pk_c_01_s_new(auth_packet); // Init packet
*(auth_packet->d_time) = time(NULL); // Set unix time in packet
strcpy(auth_packet->d_username, argv[3]); // Copy in username
strcpy(auth_packet->d_password, argv[4]); // Copy in password
// Send auth packet
if(write(sock_fd, auth_packet->buffer, auth_packet->size) < 0)
error("couldn't send auth packet");
// Destroy auth packet
pk_s_destroy(auth_packet);
// Read response packet
struct pk_s *res_packet = pk_s_read(sock_fd);
if(*(res_packet->d_packet_id) != 0x01) error("did not receive OK packet back");
if(*(res_packet->d_status) != 200) error("Authentication failed. (wrong username or password?)");
// Create Packet 0x1 S->C structure and copy data in
struct pk_s_01_s *pk_01_res = malloc(sizeof(struct pk_s_01_s));
memcpy(pk_01_res, res_packet, sizeof(struct pk_s));
free(res_packet); // Only freeing the packet struct to keep the buffer
pk_s_01_s_init(pk_01_res); // Init the pointers
strcpy(dvr_name, pk_01_res->d_name); // Copy the DVR name to the global
strcpy(dvr_vdef, pk_01_res->d_vdef); // Copy the DVR vdef to the global
pk_s_destroy(pk_01_res); // Destroy the packet
// Print some status data
fprintf(stderr, "DVR Name: %s\nVideo definition: %s\n", dvr_name, dvr_vdef);
// Authentication was successful
fprintf(stderr, "Authenticated.\n");
// Enter a loop, receive packets until a 0x99 packet is received
int packet_id = -1;
while(packet_id != 0x99) {
struct pk_s *pk = pk_s_read(sock_fd);
// Print the packet ID
fprintf(stderr, "Received packet: 0x%02x\n", *(pk->d_packet_id));
packet_id = *(pk->d_packet_id);
// Free the packet, avoid memory leaks
pk_s_destroy(pk);
}
fprintf(stderr, "Sending video stream control packet\n");
// Send a 0x03 packet to start the video stream
// Create 0x03 packet
struct pk_c_03_s *pk_03 = malloc(sizeof(struct pk_c_03_s));
pk_c_03_s_new(pk_03); // Init packet
// Send packet
if(write(sock_fd, pk_03->buffer, pk_03->size) < 0)
error("couldn't send video stream start packet");
// Destroy packet
pk_s_destroy(pk_03);
int i = 0;
// Main packet receiving loop
while(1) {
struct pk_s *pk = pk_s_read(sock_fd);
// Print the packet ID
fprintf(stderr, "Received packet: 0x%02x\n", *(pk->d_packet_id));
if(*(pk->d_packet_id) == 0x03) {
fprintf(stderr, " Video packet\n");
// Create Packet 0x3 S->C structure and copy data in
struct pk_s_03_s *pk_03_res = malloc(sizeof(struct pk_s_03_s));
memcpy(pk_03_res, pk, sizeof(struct pk_s));
free(pk); // Only freeing the packet struct to keep the buffer
pk_s_03_s_init(pk_03_res); // Init the pointers
fprintf(stderr, " Max channels: %i\n Current channel: %i\n",
*(pk_03_res->d_max_channels),
*(pk_03_res->d_channel_id));
FILE *fp = fopen("video.h264", "a");
fwrite(pk_03_res->d_video_payload, *(pk_03_res->d_video_payload_size), 1, fp);
fclose(fp);
pk_s_destroy(pk_03_res); // Destroy the packet
i++;
} else {
// Free the packet, avoid memory leaks
pk_s_destroy(pk);
}
}
// close the socket
close(sock_fd);
return 0;
}