mirror of
https://github.com/DigitalDevices/octonet.git
synced 2023-10-10 13:36:52 +02:00
Version 1.0.52
This commit is contained in:
parent
52168c5deb
commit
82f3af7881
Binary file not shown.
@ -153,7 +153,7 @@ static int set_fe(int fd, uint32_t fr, uint32_t sr, fe_delivery_system_t ds)
|
||||
struct dtv_properties c;
|
||||
int ret;
|
||||
|
||||
printf("ds = %u\n", ds);
|
||||
dbgprintf(DEBUG_DVB, "ds = %u\n", ds);
|
||||
|
||||
c.num = 7;
|
||||
c.props = p;
|
||||
@ -335,9 +335,11 @@ static int tune_sat(struct dvbfe *fe)
|
||||
fe->scif_slot, fe->scif_freq, ds);
|
||||
pthread_mutex_unlock(&fe->os->uni_lock);
|
||||
} else if (fe->scif_type == 2) {
|
||||
pthread_mutex_lock(&fe->os->uni_lock);
|
||||
set_en50607(fe->fd, freq / 1000, fe->param[PARAM_SR],
|
||||
fe->param[PARAM_SRC] - 1, fe->param[PARAM_POL] - 1, hi,
|
||||
fe->scif_slot, fe->scif_freq, ds);
|
||||
pthread_mutex_unlock(&fe->os->uni_lock);
|
||||
} else {
|
||||
diseqc(fe->fd, fe->param[PARAM_SRC] - 1, fe->param[PARAM_POL] - 1, hi);
|
||||
set_fe(fe->fd, freq, fe->param[PARAM_SR] * 1000, ds);
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include "octoserve.h"
|
||||
|
||||
extern uint32_t debug;
|
||||
|
||||
char httpxml[] =
|
||||
"HTTP/1.0 200 OK\r\nConnection: close\r\n"
|
||||
"Content-Length: %d\r\nContent-Type: text/xml\r\nMime-Version: 1.0\r\n"
|
||||
@ -44,22 +46,22 @@ char xmldesc[] =
|
||||
|
||||
"<icon>\r\n<mimetype>image/png</mimetype>\r\n"
|
||||
"<width>120</width>\r\n<height>120</height>\r\n"
|
||||
"<depth>24</depth>\r\n<url>www/icons/dd-120.png</url>\r\n"
|
||||
"<depth>24</depth>\r\n<url>/octoserve/www/icons/dd-120.png</url>\r\n"
|
||||
"</icon>\r\n"
|
||||
|
||||
"<icon>\r\n<mimetype>image/jpg</mimetype>\r\n"
|
||||
"<width>120</width>\r\n<height>120</height>\r\n"
|
||||
"<depth>24</depth>\r\n<url>www/icons/dd-120.jpg</url>\r\n"
|
||||
"<depth>24</depth>\r\n<url>/octoserve/www/icons/dd-120.jpg</url>\r\n"
|
||||
"</icon>\r\n"
|
||||
|
||||
"<icon>\r\n<mimetype>image/png</mimetype>\r\n"
|
||||
"<width>48</width>\r\n<height>48</height>\r\n"
|
||||
"<depth>24</depth>\r\n<url>www/icons/dd-48.png</url>\r\n"
|
||||
"<depth>24</depth>\r\n<url>/octoserve/www/icons/dd-48.png</url>\r\n"
|
||||
"</icon>\r\n"
|
||||
|
||||
"<icon>\r\n<mimetype>image/jpg</mimetype>\r\n"
|
||||
"<width>48</width>\r\n<height>48</height>\r\n"
|
||||
"<depth>24</depth>\r\n<url>www/icons/dd-48.jpg</url>\r\n"
|
||||
"<depth>24</depth>\r\n<url>/octoserve/www/icons/dd-48.jpg</url>\r\n"
|
||||
"</icon>\r\n"
|
||||
|
||||
"</iconList>\r\n"
|
||||
@ -363,6 +365,7 @@ void handle_http(struct os_ssdp *ss)
|
||||
send_http_error(ss->csock, 405);
|
||||
break;
|
||||
}
|
||||
dbgprintf(DEBUG_SSDP, "%s\n", buf);
|
||||
if (!strncasecmp("GET /octonet.xml", buf, 16)) {
|
||||
send_xml(ss);
|
||||
break;
|
||||
|
@ -62,8 +62,10 @@ void proc_igmp(struct octoserve *os, uint8_t *b, int l, uint8_t *macheader)
|
||||
return;
|
||||
if (cs16(p, pl) != ((p[2] << 8) | p[3])) {
|
||||
dbgprintf(DEBUG_IGMP, "IGMP CS error\n");
|
||||
#if 0
|
||||
if (debug & DEBUG_IGMP)
|
||||
dump(b, l);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@ -84,7 +86,7 @@ void proc_igmp(struct octoserve *os, uint8_t *b, int l, uint8_t *macheader)
|
||||
if (a1 < a2) {
|
||||
/* somebody else with lower IP is already sending queries */
|
||||
os->igmp_mode = 3;
|
||||
time(&os->igmp_time);
|
||||
mtime(&os->igmp_time);
|
||||
os->igmp_tag++;
|
||||
os->igmp_timeout = b[hl + 1] / 10 + 1;
|
||||
dbgprintf(DEBUG_IGMP, "IGMP slave, tag = %u, timeout = %u\n",
|
||||
@ -212,7 +214,7 @@ void check_igmp(struct octoserve *os)
|
||||
{
|
||||
time_t tdiff, t;
|
||||
|
||||
tdiff = time(&t) - os->igmp_time;
|
||||
tdiff = mtime(&t) - os->igmp_time;
|
||||
switch (os->igmp_mode) {
|
||||
case 0:
|
||||
if (tdiff > 124) {
|
||||
|
@ -119,8 +119,10 @@ int sendlen(int sock, char *buf, int len)
|
||||
int done, todo;
|
||||
|
||||
for (todo = len; todo; todo -= done, buf += done)
|
||||
if ((done = send(sock, buf, todo, 0)) < 0)
|
||||
if ((done = send(sock, buf, todo, 0)) < 0) {
|
||||
printf("sendlen error\n");
|
||||
return done;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
@ -138,3 +140,14 @@ int sendstring(int sock, char *fmt, ...)
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
time_t mtime(time_t *t)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts))
|
||||
return 0;
|
||||
if (t)
|
||||
*t = ts.tv_sec;
|
||||
return ts.tv_sec;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
(C) 2012-14 Digital Devices GmbH.
|
||||
(C) 2012-15 Digital Devices GmbH.
|
||||
|
||||
This file is part of the octoserve SAT>IP server.
|
||||
|
||||
@ -22,6 +22,19 @@
|
||||
#include <getopt.h>
|
||||
|
||||
uint32_t debug;
|
||||
uint32_t flags;
|
||||
uint32_t conform = 0;
|
||||
#define FLAGS_TRANSPORT 1
|
||||
|
||||
|
||||
uint64_t mtime_nano(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts))
|
||||
return 0;
|
||||
return ts.tv_sec * 1000000000 + ts.tv_nsec;
|
||||
}
|
||||
|
||||
void dump(const uint8_t *b, int l)
|
||||
{
|
||||
@ -313,6 +326,40 @@ static struct dvbfe *alloc_fe(struct octoserve *os, int type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void release_con(struct oscon *con)
|
||||
{
|
||||
close(con->sock);
|
||||
con->state = 0;
|
||||
dbgprintf(DEBUG_SYS, "releasing con %d\n", con->nr);
|
||||
}
|
||||
|
||||
static void shutdown_con(struct oscon *con)
|
||||
{
|
||||
con->session = 0;
|
||||
con->state = 3;
|
||||
con->timeout = mtime(NULL) + 10;
|
||||
dbgprintf(DEBUG_SYS, "shutdown con %u at %u\n", con->nr, con->timeout);
|
||||
}
|
||||
|
||||
static void *_release_session(struct ossess *oss)
|
||||
{
|
||||
struct octoserve *os = oss->os;
|
||||
int i;
|
||||
|
||||
dbgprintf(DEBUG_SYS, "releasing session %d\n", oss->nr);
|
||||
for (i = 0; i < MAX_CONNECT; i++) {
|
||||
if (os->con[i].state &&
|
||||
(os->con[i].session == oss))
|
||||
shutdown_con(&os->con[i]);
|
||||
}
|
||||
if (oss->nsfd >= 0) {
|
||||
dbgprintf(DEBUG_SYS, "closing netstream of session %d\n", oss->nr);
|
||||
close(oss->nsfd);
|
||||
}
|
||||
oss->playing = 0;
|
||||
oss->state = 0;
|
||||
}
|
||||
|
||||
static void *release_stream(struct osstrm *str)
|
||||
{
|
||||
struct octoserve *os = str->os;
|
||||
@ -321,8 +368,8 @@ static void *release_stream(struct osstrm *str)
|
||||
|
||||
for (i = 0; i < MAX_SESSION; i++) {
|
||||
if (os->session[i].state &&
|
||||
os->session[i].stream == str)
|
||||
os->session[i].stream = 0;
|
||||
(os->session[i].stream == str))
|
||||
_release_session(&os->session[i]);
|
||||
}
|
||||
str->state = 0;
|
||||
release_fe(os, str->fe);
|
||||
@ -347,8 +394,7 @@ static struct osstrm *alloc_stream(struct octoserve *os)
|
||||
str->sport2 = 8000 + 2 * i + 1;
|
||||
pthread_mutex_unlock(&os->lock);
|
||||
dbgprintf(DEBUG_SYS, "Allocated stream %d\n", str->nr);
|
||||
return str;
|
||||
}
|
||||
return str;}
|
||||
}
|
||||
pthread_mutex_unlock(&os->lock);
|
||||
return NULL;
|
||||
@ -362,7 +408,7 @@ static struct osstrm *get_stream(struct octoserve *os, int id)
|
||||
pthread_mutex_lock(&os->lock);
|
||||
for (i = 0; i < MAX_STREAM; i++) {
|
||||
str = &os->stream[i];
|
||||
if (str->state && str->nr == id) {
|
||||
if (str->state && (str->nr == id)) {
|
||||
r = str;
|
||||
break;
|
||||
}
|
||||
@ -379,21 +425,10 @@ static void *release_session(struct ossess *oss)
|
||||
dbgprintf(DEBUG_SYS, "release session nr %d id %010d\n", oss->nr, oss->id);
|
||||
pthread_mutex_lock(&os->lock);
|
||||
mc_del(oss);
|
||||
if (oss->stream) {
|
||||
if (oss->stream->session == oss)
|
||||
if (oss->stream && (oss->stream->session == oss)) // stream owner?
|
||||
release_stream(oss->stream);
|
||||
}
|
||||
for (i = 0; i < MAX_CONNECT; i++) {
|
||||
if (os->con[i].state &&
|
||||
os->con[i].session == oss)
|
||||
os->con[i].session = 0;
|
||||
}
|
||||
if (oss->nsfd >= 0) {
|
||||
dbgprintf(DEBUG_SYS, "close NS\n");
|
||||
close(oss->nsfd);
|
||||
}
|
||||
oss->playing = 0;
|
||||
oss->state = 0;
|
||||
else
|
||||
_release_session(oss);
|
||||
pthread_mutex_unlock(&os->lock);
|
||||
}
|
||||
|
||||
@ -405,7 +440,7 @@ static struct ossess *get_session(struct octoserve *os, uint32_t id)
|
||||
pthread_mutex_lock(&os->lock);
|
||||
for (i = 0; i < MAX_SESSION; i++) {
|
||||
oss = &os->session[i];
|
||||
if (oss->state && oss->id == id) {
|
||||
if (oss->state && (oss->id == id)) {
|
||||
pthread_mutex_unlock(&os->lock);
|
||||
return oss;
|
||||
}
|
||||
@ -417,11 +452,12 @@ static struct ossess *get_session(struct octoserve *os, uint32_t id)
|
||||
static void check_mccs(struct ossess *sess)
|
||||
{
|
||||
time_t tdiff, t;
|
||||
int update = 0;
|
||||
|
||||
if (!sess->trans.mcast)
|
||||
return;
|
||||
|
||||
tdiff = time(&t) - sess->mcc_time;
|
||||
tdiff = mtime(&t) - sess->mcc_time;
|
||||
switch (sess->mcc_state) {
|
||||
case 1:
|
||||
if (tdiff >= 1) {
|
||||
@ -441,21 +477,23 @@ static void check_mccs(struct ossess *sess)
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
if (tdiff >= 4) {
|
||||
if (tdiff >= 2) {
|
||||
sess->mcc_state = 0;
|
||||
sess->mcc_time = t;
|
||||
printf("%u: mcc_state 2 done, tag = %d\n", t, sess->mcc_tag);
|
||||
update = 1;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
update = 1;
|
||||
break;
|
||||
}
|
||||
mc_check(sess);
|
||||
mc_check(sess, update);
|
||||
}
|
||||
|
||||
void session_timeout(struct ossess *sess)
|
||||
{
|
||||
time(&sess->timeout);
|
||||
mtime(&sess->timeout);
|
||||
sess->timeout += sess->timeout_len;
|
||||
dbgprintf(DEBUG_RTSP, "new timeout %d\n", sess->timeout);
|
||||
}
|
||||
@ -466,14 +504,14 @@ void check_session_timeouts(struct octoserve *os)
|
||||
int i;
|
||||
struct ossess *sess;
|
||||
|
||||
time(&t);
|
||||
mtime(&t);
|
||||
pthread_mutex_lock(&os->lock);
|
||||
for (i = 0; i < MAX_SESSION; i++) {
|
||||
sess = &os->session[i];
|
||||
check_mccs(sess);
|
||||
|
||||
if (sess->state &&
|
||||
sess->timeout < t) {
|
||||
(sess->timeout < t)) {
|
||||
struct oscon *con;
|
||||
int j;
|
||||
|
||||
@ -482,7 +520,7 @@ void check_session_timeouts(struct octoserve *os)
|
||||
for (j = 0; j < MAX_CONNECT; j++) {
|
||||
con = &os->con[j];
|
||||
if (con->state && con->session &&
|
||||
con->session == sess) {
|
||||
(con->session == sess)) {
|
||||
session_timeout(sess);
|
||||
break;
|
||||
}
|
||||
@ -503,7 +541,7 @@ static uint32_t get_id(struct octoserve *os)
|
||||
id = random();
|
||||
for (i = 0; i < MAX_SESSION; i++) {
|
||||
oss = &os->session[i];
|
||||
if (oss->state && oss->id == id)
|
||||
if (oss->state && (oss->id == id))
|
||||
break;
|
||||
}
|
||||
if (i == MAX_SESSION)
|
||||
@ -530,7 +568,7 @@ static struct ossess *alloc_session(struct octoserve *os)
|
||||
oss->timeout_len = 60;
|
||||
session_timeout(oss);
|
||||
LIST_INIT(&oss->mccs);
|
||||
time(&oss->mcc_time);
|
||||
mtime(&oss->mcc_time);
|
||||
dbgprintf(DEBUG_SYS,
|
||||
"Allocated session nr=%d id=%d\n",
|
||||
oss->nr, oss->id);
|
||||
@ -542,13 +580,6 @@ static struct ossess *alloc_session(struct octoserve *os)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *release_con(struct oscon *con)
|
||||
{
|
||||
close(con->sock);
|
||||
con->state = 0;
|
||||
dbgprintf(DEBUG_SYS, "released con %d\n", con->nr);
|
||||
}
|
||||
|
||||
static struct oscon *alloc_con(struct octoserve *os)
|
||||
{
|
||||
int i;
|
||||
@ -593,7 +624,7 @@ static void send_option(struct oscon *con)
|
||||
"%s"
|
||||
"\r\n",
|
||||
con->seq, opt);
|
||||
if (len > 0 && len < sizeof(buf)) {
|
||||
if ((len > 0) && (len < sizeof(buf))) {
|
||||
sendlen(con->sock, buf, len);
|
||||
dbgprintf(DEBUG_RTSP, "Send: %s\n", buf);
|
||||
}
|
||||
@ -736,7 +767,7 @@ static int send_describe(struct oscon *con, int only)
|
||||
{
|
||||
struct osstrm *str;
|
||||
struct ostrans *t;
|
||||
uint8_t buf[4096], buf2[1024], buf3[1024];
|
||||
uint8_t buf[4096], buf2[4096 + 1024], buf3[1024];
|
||||
int len, len2, i;
|
||||
int start = 0, end = MAX_STREAM;
|
||||
char *p;
|
||||
@ -756,12 +787,18 @@ static int send_describe(struct oscon *con, int only)
|
||||
return -404;
|
||||
#endif
|
||||
if (only >= 0) {
|
||||
if (only >= MAX_STREAM)
|
||||
return -404;
|
||||
start = only - 1;
|
||||
end = only;
|
||||
str = &con->os->stream[start];
|
||||
if (!str->state)
|
||||
return -404;
|
||||
}
|
||||
if (con->os->dvbtnum + con->os->dvbt2num + con->os->dvbcnum + con->os->dvbc2num)
|
||||
len = snprintf(buf, sizeof(buf),
|
||||
"v=0\r\n"
|
||||
"o=- 5678901234 1 IN %s %s\r\n"
|
||||
"o=- 5678901234 7890123456 IN %s %s\r\n"
|
||||
"s=SatIPServer:1 %d,%d,%d\r\n"
|
||||
"t=0 0\r\n",
|
||||
con->trans.family == AF_INET ? "IP4" : "IP6",
|
||||
@ -770,10 +807,22 @@ static int send_describe(struct oscon *con, int only)
|
||||
con->os->dvbtnum + con->os->dvbt2num,
|
||||
con->os->dvbcnum + con->os->dvbc2num
|
||||
);
|
||||
else
|
||||
len = snprintf(buf, sizeof(buf),
|
||||
"v=0\r\n"
|
||||
"o=- 5678901234 7890123456 IN %s %s\r\n"
|
||||
"s=SatIPServer:1 %d\r\n"
|
||||
"t=0 0\r\n",
|
||||
con->trans.family == AF_INET ? "IP4" : "IP6",
|
||||
con->sadr_ip,
|
||||
con->os->dvbs2num
|
||||
);
|
||||
|
||||
if (len <= 0 || len >= sizeof(buf))
|
||||
return -500;
|
||||
for (i = start; i < end; i++) {
|
||||
char *adr = "0.0.0.0", abuf[32];
|
||||
int j, sendonly = 0;
|
||||
int alen;
|
||||
|
||||
str = &con->os->stream[i];
|
||||
@ -781,6 +830,12 @@ static int send_describe(struct oscon *con, int only)
|
||||
continue;
|
||||
t = &str->session->trans;
|
||||
|
||||
for (j = sendonly = 0; j < MAX_SESSION; j++) {
|
||||
if (con->os->session[j].state &&
|
||||
con->os->session[j].stream == str &&
|
||||
con->os->session[j].playing)
|
||||
sendonly = 1;
|
||||
}
|
||||
session_string(str->session, buf3, sizeof(buf3));
|
||||
|
||||
if (t->mcast) {
|
||||
@ -808,21 +863,29 @@ static int send_describe(struct oscon *con, int only)
|
||||
adr,
|
||||
str->nr,
|
||||
buf3,
|
||||
str->session->playing ? "sendonly" : "inactive"
|
||||
sendonly ? "sendonly" : "inactive"
|
||||
);
|
||||
if (len2 <= 0 || len2 >= sizeof(buf) - len)
|
||||
return -500;
|
||||
len += len2;
|
||||
}
|
||||
len2=sprintf(buf2, "RTSP/1.0 200 OK\r\nCSeq: %d\r\n"
|
||||
len2 = sprintf(buf2, "RTSP/1.0 200 OK\r\nCSeq: %d\r\n"
|
||||
"Content-Type: application/sdp\r\n"
|
||||
"Content-Base: rtsp://%s/\r\n"
|
||||
"Content-Length: %d\r\n"
|
||||
"\r\n",
|
||||
con->seq, con->sadr_ip, len);
|
||||
|
||||
/* URGH, some receivers (cough Kathr** cough) cannot handle
|
||||
split RTSP messages */
|
||||
#if 0
|
||||
sendlen(con->sock, buf2, len2);
|
||||
sendlen(con->sock, buf, len);
|
||||
#else
|
||||
memcpy(buf2 + len2, buf, len);
|
||||
sendlen(con->sock, buf2, len + len2);
|
||||
//dump(buf2, len + len2);
|
||||
#endif
|
||||
dbgprintf(DEBUG_RTSP, "Send:\n%s", buf2);
|
||||
dbgprintf(DEBUG_RTSP, "%s\n", buf);
|
||||
return 0;
|
||||
@ -1279,17 +1342,27 @@ static int setup_nsp(struct ostrans *trans, struct dvb_ns_params *nsp)
|
||||
|
||||
static int merge_pids(struct dvb_params *op, struct dvb_params *p)
|
||||
{
|
||||
int i;
|
||||
int i, r = 0;
|
||||
|
||||
if (p->set & (1UL << PARAM_PID))
|
||||
for (i = 0 ; i < 1024 ; i++)
|
||||
if (op->pid[i] != p->pid[i]) {
|
||||
r |= 1;
|
||||
op->pid[i] = p->pid[i];
|
||||
}
|
||||
if (p->set & (1UL << PARAM_APID))
|
||||
for (i = 0 ; i < 1024 ; i++)
|
||||
if (!(op->pid[i] & p->pid[i])) {
|
||||
r |= 2;
|
||||
op->pid[i] |= p->pid[i];
|
||||
}
|
||||
if (p->set & (1UL << PARAM_DPID))
|
||||
for (i = 0 ; i < 1024 ; i++)
|
||||
if (op->pid[i] & p->dpid[i]) {
|
||||
r |= 4;
|
||||
op->pid[i] &= ~p->dpid[i];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int merge_params(struct dvb_params *op, struct dvb_params *p)
|
||||
@ -1318,6 +1391,10 @@ static int setup_session(struct oscon *con, int newtrans)
|
||||
|
||||
if (!str)
|
||||
return -500;
|
||||
if (conform) {
|
||||
if (str->session != sess && merge_pids(sp, p) < 0)
|
||||
return -455;
|
||||
} else
|
||||
merge_pids(sp, p);
|
||||
if (str->session == sess) { /* stream owner */
|
||||
merge_params(sp, p);
|
||||
@ -1356,6 +1433,10 @@ static int setup_session(struct oscon *con, int newtrans)
|
||||
newtrans = 1;
|
||||
}
|
||||
if (newtrans) {
|
||||
if (str->session != sess &&
|
||||
sess->trans.mcast &&
|
||||
conform)
|
||||
return -455;
|
||||
if (setup_nsp(&sess->trans, &nsp) < 0)
|
||||
return -1;
|
||||
if (set_ns(sess, &nsp) < 0)
|
||||
@ -1412,8 +1493,7 @@ static int start_session(struct ossess *sess)
|
||||
{
|
||||
if (sess->playing)
|
||||
return 0;
|
||||
dbgprintf(DEBUG_SYS, "START\n");
|
||||
printf("start session %d\n", sess->nr);
|
||||
dbgprintf(DEBUG_SYS, "start session %d\n", sess->nr);
|
||||
if (sess->stream->ca) {
|
||||
uint8_t canum = sess->stream->ca->nr - 1;
|
||||
if (sess->nsfd >= 0)
|
||||
@ -1465,7 +1545,7 @@ static struct ossess *match_session(struct octoserve *os, uint8_t *group)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mc_check(struct ossess *sess)
|
||||
void mc_check(struct ossess *sess, int update)
|
||||
{
|
||||
struct osmcc *mcc, *next;
|
||||
struct octoserve *os = sess->os;
|
||||
@ -1485,10 +1565,12 @@ void mc_check(struct ossess *sess)
|
||||
free(mcc);
|
||||
}
|
||||
}
|
||||
if (update) {
|
||||
if (os->has_switch)
|
||||
update_switch_vec(sess);
|
||||
if (!sess->mccs.lh_first)
|
||||
stop_session(sess);
|
||||
}
|
||||
pthread_mutex_unlock(&os->lock);
|
||||
}
|
||||
|
||||
@ -1575,7 +1657,7 @@ void mc_query(struct ossess *sess)
|
||||
{
|
||||
/* query in group if anybody still there */
|
||||
if (!sess->mcc_state) {
|
||||
time(&sess->mcc_time);
|
||||
mtime(&sess->mcc_time);
|
||||
sess->mcc_state = 1;
|
||||
}
|
||||
}
|
||||
@ -1617,7 +1699,6 @@ static void send_play(struct oscon *con)
|
||||
uint8_t buf[1024];
|
||||
int len;
|
||||
|
||||
dbgprintf(DEBUG_SYS, "%s\n", __FUNCTION__);
|
||||
len = sprintf(buf,
|
||||
"RTSP/1.0 200 OK\r\n"
|
||||
"CSeq: %d\r\n"
|
||||
@ -1800,6 +1881,123 @@ static void cpyarg(char *d, char *s)
|
||||
strcpy(d, s);
|
||||
}
|
||||
|
||||
|
||||
static int cmp_trans(struct ostrans *t, struct ostrans *u)
|
||||
{
|
||||
if (t->mcast != u->mcast)
|
||||
return 1;
|
||||
|
||||
if (t->cport != u->cport)
|
||||
return 2;
|
||||
if (t->cport2 != u->cport2)
|
||||
return 3;
|
||||
if (t->flags != u->flags)
|
||||
return 4;
|
||||
if (t->ttl != u->ttl)
|
||||
return 5;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int proc_setup(struct oscon *con)
|
||||
{
|
||||
struct osstrm *str = 0;
|
||||
int newtrans = 0;
|
||||
int res;
|
||||
|
||||
if (!con->transport_parsed) {
|
||||
/* no proper transport params given */
|
||||
send_error(con, 400);
|
||||
return -1;
|
||||
}
|
||||
if (con->session_parsed && !con->session) {
|
||||
/* no session with given ID found */
|
||||
send_error(con, 454);
|
||||
return -1;
|
||||
}
|
||||
if (parse_url(con, 0) < 0) {
|
||||
/* invalid params in URL */
|
||||
send_error(con, 400);
|
||||
return -1;
|
||||
}
|
||||
if (con->p.set & (1UL << PARAM_STREAMID)) {
|
||||
dbgprintf(DEBUG_SYS, "existing stream %d\n",
|
||||
con->p.param[PARAM_STREAMID]);
|
||||
str = get_stream(con->os, con->p.param[PARAM_STREAMID]);
|
||||
if (!str) {
|
||||
/* no stream with given ID */
|
||||
send_error(con, 400);
|
||||
return -1;
|
||||
}
|
||||
if (con->session && con->session != str->session) {
|
||||
/* if we already have a session ID we
|
||||
have to be stream owner */
|
||||
send_error(con, 400);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (!con->session) {
|
||||
/* alloc new session */
|
||||
con->session = alloc_session(con->os);
|
||||
if (!con->session) {
|
||||
send_error(con, 400);
|
||||
return -1;
|
||||
}
|
||||
con->state = 2;
|
||||
if (!con->session->stream) {
|
||||
if (str) {
|
||||
/* use existing stream and stream params*/
|
||||
con->session->stream = str;
|
||||
if (con->session->stream->session) {
|
||||
memcpy(&con->session->p,
|
||||
&con->session->stream->session->p,
|
||||
sizeof(struct dvb_params));
|
||||
}
|
||||
} else {
|
||||
con->session->stream = alloc_stream(con->os);
|
||||
if (!con->session->stream) {
|
||||
send_error(con, 400);
|
||||
return -1;
|
||||
}
|
||||
con->session->stream->session = con->session;
|
||||
}
|
||||
}
|
||||
newtrans = 1;
|
||||
}
|
||||
if (newtrans || cmp_trans(&con->session->trans, &con->trans)) {
|
||||
con->trans.sport = con->session->stream->sport;
|
||||
con->trans.sport2 = con->session->stream->sport2;
|
||||
|
||||
/* set transport struct according to session
|
||||
and transport parameters */
|
||||
if (con->trans.mcast && con->trans.cport == 0) {
|
||||
con->trans.cport = con->trans.sport;
|
||||
con->trans.cport2 = con->trans.sport2;
|
||||
}
|
||||
|
||||
if (con->trans.mcast &&
|
||||
!(con->trans.flags & TRANS_ALT_DEST)) {
|
||||
uint8_t mac[6] = { 0x01, 0x00, 0x5e,
|
||||
con->os->ssdp.devid & 0x7f, 1,
|
||||
con->session->stream->nr };
|
||||
uint8_t ip[4] = { 239, con->os->ssdp.devid, 1,
|
||||
con->session->stream->nr };
|
||||
|
||||
memcpy(con->trans.mcmac, mac, 6);
|
||||
memcpy(con->trans.mcip, ip, 4);
|
||||
}
|
||||
con->session->trans = con->trans;
|
||||
newtrans = 1;
|
||||
}
|
||||
res = setup_session(con, newtrans);
|
||||
if (res < 0) {
|
||||
release_session(con->session);
|
||||
send_error(con, -res);
|
||||
} else
|
||||
send_setup(con);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int proc_line(struct oscon *con)
|
||||
{
|
||||
char *line = con->buf;
|
||||
@ -1858,107 +2056,11 @@ static int proc_line(struct oscon *con)
|
||||
send_error(con, -res);
|
||||
break;
|
||||
}
|
||||
|
||||
case M_SETUP:
|
||||
{
|
||||
struct osstrm *str = 0;
|
||||
int newtrans = 0;
|
||||
proc_setup(con);
|
||||
break;
|
||||
|
||||
if (!con->transport_parsed) {
|
||||
/* no proper transport params given */
|
||||
send_error(con, 400);
|
||||
break;
|
||||
}
|
||||
if (con->session_parsed && !con->session) {
|
||||
/* no session with given ID found */
|
||||
send_error(con, 454);
|
||||
break;
|
||||
}
|
||||
if (parse_url(con, 0) < 0) {
|
||||
/* invalid params in URL */
|
||||
send_error(con, 400);
|
||||
break;
|
||||
}
|
||||
if (con->p.set & (1UL << PARAM_STREAMID)) {
|
||||
dbgprintf(DEBUG_SYS, "existing stream %d\n",
|
||||
con->p.param[PARAM_STREAMID]);
|
||||
str = get_stream(con->os, con->p.param[PARAM_STREAMID]);
|
||||
if (!str) {
|
||||
/* no stream with given ID */
|
||||
send_error(con, 400);
|
||||
break;
|
||||
}
|
||||
if (con->session && con->session != str->session) {
|
||||
/* if we already have a session ID we
|
||||
have to be stream owner */
|
||||
send_error(con, 400);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!con->session) {
|
||||
/* alloc new session */
|
||||
con->session = alloc_session(con->os);
|
||||
if (!con->session) {
|
||||
send_error(con, 400);
|
||||
break;
|
||||
}
|
||||
if (!con->session->stream) {
|
||||
if (str) {
|
||||
/* use existing stream and stream params*/
|
||||
con->session->stream = str;
|
||||
if (con->session->stream->session) {
|
||||
memcpy(&con->session->p,
|
||||
&con->session->stream->session->p,
|
||||
sizeof(struct dvb_params));
|
||||
}
|
||||
} else {
|
||||
con->session->stream = alloc_stream(con->os);
|
||||
if (!con->session->stream) {
|
||||
send_error(con, 400);
|
||||
break;
|
||||
}
|
||||
con->session->stream->session = con->session;
|
||||
}
|
||||
}
|
||||
newtrans = 1;
|
||||
}
|
||||
if (newtrans ||
|
||||
con->session->trans.mcast != con->trans.mcast ||
|
||||
con->session->trans.cport != con->trans.cport ||
|
||||
con->session->trans.cport2 != con->trans.cport2 ||
|
||||
con->session->trans.flags != con->trans.flags ||
|
||||
con->session->trans.ttl != con->trans.ttl) {
|
||||
con->trans.sport = con->session->stream->sport;
|
||||
con->trans.sport2 = con->session->stream->sport2;
|
||||
|
||||
/* set transport struct according to session
|
||||
and transport parameters */
|
||||
if (con->trans.mcast && con->trans.cport == 0) {
|
||||
con->trans.cport = con->trans.sport;
|
||||
con->trans.cport2 = con->trans.sport2;
|
||||
}
|
||||
|
||||
if (con->trans.mcast &&
|
||||
!(con->trans.flags & TRANS_ALT_DEST)) {
|
||||
uint8_t mac[6] = { 0x01, 0x00, 0x5e,
|
||||
con->os->ssdp.devid & 0x7f, 1,
|
||||
con->session->stream->nr };
|
||||
uint8_t ip[4] = { 239, con->os->ssdp.devid, 1,
|
||||
con->session->stream->nr };
|
||||
|
||||
memcpy(con->trans.mcmac, mac, 6);
|
||||
memcpy(con->trans.mcip, ip, 4);
|
||||
}
|
||||
con->session->trans = con->trans;
|
||||
newtrans = 1;
|
||||
}
|
||||
res = setup_session(con, newtrans);
|
||||
if (res < 0) {
|
||||
release_session(con->session);
|
||||
send_error(con, -res);
|
||||
} else
|
||||
send_setup(con);
|
||||
break;
|
||||
}
|
||||
case M_PLAY:
|
||||
if (!con->session || !con->session->stream) {
|
||||
send_error(con, 400);
|
||||
@ -1989,7 +2091,6 @@ static int proc_line(struct oscon *con)
|
||||
}
|
||||
send_teardown(con);
|
||||
release_session(con->session);
|
||||
con->session = 0;
|
||||
break;
|
||||
default:
|
||||
send_error(con, 501);
|
||||
@ -2019,6 +2120,7 @@ static int proc_line(struct oscon *con)
|
||||
con->session = get_session(con->os, sid);
|
||||
if (con->session)
|
||||
session_timeout(con->session);
|
||||
con->state = 2;
|
||||
con->session_parsed = 1;
|
||||
} else if (!strncasecmp(line, "User-Agent:", 11)) {
|
||||
char *p = line + 11;
|
||||
@ -2106,6 +2208,19 @@ static void init_con(struct oscon *con)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void con_check(struct octoserve *os)
|
||||
{
|
||||
int i;
|
||||
time_t t = mtime(NULL);
|
||||
|
||||
for (i = 0; i < MAX_CONNECT; i++) {
|
||||
if (os->con[i].state == 3 &&
|
||||
t > os->con[i].timeout)
|
||||
release_con(&os->con[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int con_loop(struct oscon *con)
|
||||
{
|
||||
uint8_t buf[1024];
|
||||
@ -2119,20 +2234,19 @@ int con_loop(struct oscon *con)
|
||||
goto release;
|
||||
return 0;
|
||||
}
|
||||
if (debug & DEBUG_RTSP)
|
||||
dump(buf, len);
|
||||
//printf("received %d bytes\n", len);
|
||||
for (i = 0; i < len; i++) {
|
||||
// FIXME send URI too long
|
||||
if (con->bufp >= 8192) {
|
||||
release_con(con);
|
||||
return -1;
|
||||
goto release;
|
||||
}
|
||||
con->buf[con->bufp++] = buf[i];
|
||||
if (buf[i] == '\n') {
|
||||
if (con->bufp < 2 ||
|
||||
con->buf[con->bufp - 2] != '\r') {
|
||||
release_con(con);
|
||||
return -1;
|
||||
goto release;
|
||||
}
|
||||
con->buf[con->bufp - 2] = 0;
|
||||
if (con->buf[0])
|
||||
@ -2146,6 +2260,7 @@ int con_loop(struct oscon *con)
|
||||
}
|
||||
return 0;
|
||||
release:
|
||||
dbgprintf(DEBUG_SYS, "release\n");
|
||||
release_con(con);
|
||||
return -1;
|
||||
}
|
||||
@ -2231,7 +2346,7 @@ static int alloc_igmp_socket(struct octoserve *os)
|
||||
&one, sizeof(one));
|
||||
setsockopt(os->igmp_sock, IPPROTO_IP, IP_ROUTER_ALERT,
|
||||
&one, sizeof(one));
|
||||
time(&os->igmp_time);
|
||||
mtime(&os->igmp_time);
|
||||
/* first query after 125-94=31 seconds */
|
||||
os->igmp_mode = 0;
|
||||
os->igmp_time -= 94;
|
||||
@ -2326,7 +2441,7 @@ static void os_serve(struct octoserve *os)
|
||||
&imr, sizeof(imr));
|
||||
}
|
||||
#endif
|
||||
time(&t);
|
||||
mtime(&t);
|
||||
while (!os->exit) {
|
||||
int csock, ncon;
|
||||
struct sockaddr cadr;
|
||||
@ -2334,7 +2449,7 @@ static void os_serve(struct octoserve *os)
|
||||
uint8_t buf[2048];
|
||||
int num, n;
|
||||
|
||||
time(&u);
|
||||
mtime(&u);
|
||||
if (u > t) {
|
||||
t = u;
|
||||
check_session_timeouts(os);
|
||||
@ -2384,6 +2499,8 @@ static void os_serve(struct octoserve *os)
|
||||
FD_ISSET(os->con[i].sock, &fds))
|
||||
con_loop(&os->con[i]);
|
||||
#endif
|
||||
con_check(os);
|
||||
|
||||
|
||||
if (FD_ISSET(os->rtsp_sock, &fds)) {
|
||||
struct oscon *con;
|
||||
@ -2521,20 +2638,23 @@ int main(int argc, char **argv)
|
||||
printf("Octoserve " OCTOSERVE_VERSION
|
||||
", Copyright (C) 2012-15 Digital Devices GmbH\n");
|
||||
debug = 0;
|
||||
flags = 0;
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
int c;
|
||||
static struct option long_options[] = {
|
||||
{"debug", required_argument, 0, 'd'},
|
||||
{"flags", required_argument, 0, 'f'},
|
||||
{"nossdp", no_argument, 0, 'n'},
|
||||
{"nodms", no_argument, 0, 'm'},
|
||||
{"nodvbt", no_argument, 0, 't'},
|
||||
{"noswitch", no_argument, 0, 's'},
|
||||
{"conform", no_argument, 0, 'c'},
|
||||
{"help", no_argument , 0, 'h'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
c = getopt_long(argc, argv,
|
||||
"d:hnmt",
|
||||
"d:f:nmtsch",
|
||||
long_options, &option_index);
|
||||
if (c==-1)
|
||||
break;
|
||||
@ -2543,6 +2663,9 @@ int main(int argc, char **argv)
|
||||
case 'd':
|
||||
debug = strtoul(optarg, NULL, 16);
|
||||
break;
|
||||
case 'f':
|
||||
flags = strtoul(optarg, NULL, 16);
|
||||
break;
|
||||
case 'n':
|
||||
nossdp = 1;
|
||||
break;
|
||||
@ -2555,6 +2678,9 @@ int main(int argc, char **argv)
|
||||
case 's':
|
||||
noswitch = 1;
|
||||
break;
|
||||
case 'c':
|
||||
conform = 1;
|
||||
break;
|
||||
case 'h':
|
||||
default:
|
||||
break;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
(C) 2012-13 Digital Devices GmbH.
|
||||
(C) 2012-15 Digital Devices GmbH.
|
||||
|
||||
This file is part of the octoserve SAT>IP server.
|
||||
|
||||
@ -73,9 +73,14 @@
|
||||
#define DEBUG_IGMP 32
|
||||
#define DEBUG_SWITCH 64
|
||||
|
||||
#if 0
|
||||
#define dbgprintf(_mask_, ...) \
|
||||
do { if (debug & _mask_) fprintf(stderr, __VA_ARGS__); } while (0)
|
||||
|
||||
#else
|
||||
#define dbgprintf(_mask_, ...) \
|
||||
do { if (debug & _mask_) { fprintf(stderr, "[%5u] ", mtime(NULL)); \
|
||||
fprintf(stderr, __VA_ARGS__); } } while (0)
|
||||
#endif
|
||||
|
||||
#define SYS_DVBC2 19
|
||||
|
||||
@ -339,6 +344,8 @@ struct oscon {
|
||||
int sock;
|
||||
int nr;
|
||||
|
||||
time_t timeout;
|
||||
|
||||
struct ostrans trans;
|
||||
|
||||
struct sockaddr cadr;
|
||||
@ -444,6 +451,7 @@ struct octoserve {
|
||||
int scif_type;
|
||||
int has_feswitch;
|
||||
int do_feswitch;
|
||||
int strict_satip;
|
||||
|
||||
int dvbfe_num;
|
||||
struct dvbfe dvbfe[MAX_DVB_FE];
|
||||
@ -501,7 +509,7 @@ void dump(const uint8_t *b, int l);
|
||||
void proc_igmp(struct octoserve *os, uint8_t *b, int l, uint8_t *mh);
|
||||
void mc_join(struct octoserve *os, uint8_t *ip, uint8_t *mac, uint8_t *group);
|
||||
void mc_leave(struct octoserve *os, uint8_t *ip, uint8_t *group);
|
||||
void mc_check(struct ossess *sess);
|
||||
void mc_check(struct ossess *sess, int update);
|
||||
void mc_del(struct ossess *sess);
|
||||
|
||||
void send_igmp_query(struct octoserve *os, uint8_t *group, uint8_t timeout);
|
||||
@ -519,4 +527,6 @@ int set_nonblock(int fd);
|
||||
int sendlen(int sock, char *buf, int len);
|
||||
int sendstring(int sock, char *fmt, ...);
|
||||
|
||||
time_t mtime(time_t *t);
|
||||
|
||||
#endif
|
||||
|
@ -26,9 +26,9 @@ extern uint32_t debug;
|
||||
static void ssdp_reset_setup(struct os_ssdp *ss)
|
||||
{
|
||||
ss->setup = 0;
|
||||
time(&ss->setupt);
|
||||
mtime(&ss->setupt);
|
||||
ss->setupt += 5;
|
||||
time(&ss->annt);
|
||||
mtime(&ss->annt);
|
||||
}
|
||||
|
||||
static int read_id(char *type, uint32_t *id)
|
||||
@ -171,7 +171,7 @@ static int ssdp_announce(struct octoserve *os, int alive, int notify)
|
||||
time_t t;
|
||||
|
||||
if (notify) {
|
||||
time(&t);
|
||||
mtime(&t);
|
||||
if (!ss->setup)
|
||||
if (t >= ss->setupt) {
|
||||
ss->setup = 1;
|
||||
@ -194,7 +194,7 @@ static int ssdp_defend(struct os_ssdp *ss)
|
||||
int s = ss->v6 ? ss->sock6 : ss->sock;
|
||||
|
||||
sockname(&ss->cadr, host);
|
||||
printf("defend against HOST:%s\n", host);
|
||||
dbgprintf(DEBUG_SSDP, "defend against HOST:%s\n", host);
|
||||
|
||||
len = snprintf(buf, sizeof(buf),
|
||||
"M-SEARCH * HTTP/1.1\r\n"
|
||||
@ -335,7 +335,7 @@ static void handle_ssdp(struct octoserve *os, char *m, int ml)
|
||||
}
|
||||
for (tl = 0; tl < ll && l[tl] != ':'; tl++);
|
||||
if (tl == ll)
|
||||
return;
|
||||
continue;
|
||||
for (as = tl + 1; as < ll && isspace(l[as]); as++);
|
||||
al = ll - as;
|
||||
|
||||
@ -344,8 +344,11 @@ static void handle_ssdp(struct octoserve *os, char *m, int ml)
|
||||
|
||||
if (!strncmp(l + as, "239.255.255.250:1900", al))
|
||||
htype = 1;
|
||||
else
|
||||
else {
|
||||
htype = 2;
|
||||
if (mx < 0)
|
||||
mx = 1;
|
||||
}
|
||||
h = host;
|
||||
p = l + as;
|
||||
while (*p && *p != ':')
|
||||
@ -389,16 +392,17 @@ static void handle_ssdp(struct octoserve *os, char *m, int ml)
|
||||
}
|
||||
}
|
||||
ss->csport = sport;
|
||||
dbgprintf(DEBUG_SSDP, "host=%s, hport=%u, type=%d, htype=%d mx=%d\n", host, hport, type, htype, mx);
|
||||
dbgprintf(DEBUG_SSDP, "host=%s, hport=%u, type=%d, htype=%d mx=%d\n",
|
||||
host, hport, type, htype, mx);
|
||||
/* M-SEARCH */
|
||||
if (ss->setup) {
|
||||
if (type == 1 && mx > 0) {
|
||||
//ssdp_msearch(ss, htype == 2 ? 0 : 1, st);
|
||||
ssdp_msearch(ss, 0, st);
|
||||
}
|
||||
/* NOTIFY */
|
||||
if (type == 2 && devid == ss->devid && memcmp(uu, ss->uuid, 16)) {
|
||||
if (type == 2 && devid == ss->devid && memcmp(uu, ss->uuid, 16))
|
||||
ssdp_defend(ss);
|
||||
}
|
||||
} else {
|
||||
if (type == 1 && htype == 2 && ss->devid == devid) {
|
||||
send_reply_msearch(ss, 0, 1, 2);
|
||||
|
@ -84,7 +84,20 @@ int mdio_wait_switch(int fd, uint8_t adr, uint8_t reg)
|
||||
|
||||
int mdio_open()
|
||||
{
|
||||
return open("/dev/ddbridge/card0", O_RDWR);
|
||||
int i, r;
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
r = open("/dev/ddbridge/card0", O_RDWR);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
if (r < 0)
|
||||
if (errno != EBUSY)
|
||||
return r;
|
||||
else
|
||||
usleep(100000);
|
||||
}
|
||||
dbgprintf(DEBUG_SWITCH, "MDIO BUSY\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
int mdio_close(int fd)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
(C) 2012-13 Digital Devices GmbH.
|
||||
(C) 2012-15 Digital Devices GmbH.
|
||||
|
||||
This file is part of the octoserve SAT>IP server.
|
||||
|
||||
@ -19,5 +19,5 @@
|
||||
|
||||
#ifndef _OCTOSERVE_VERSION_
|
||||
#define _OCTOSERVE_VERSION_
|
||||
#define OCTOSERVE_VERSION "1.0.46"
|
||||
#define OCTOSERVE_VERSION "1.0.52"
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user