1
0
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:
Ralph Metzler 2015-08-31 21:29:53 +02:00
parent 52168c5deb
commit 82f3af7881
10 changed files with 385 additions and 212 deletions

Binary file not shown.

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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;
}

View File

@ -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)
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;
if (oss->stream && (oss->stream->session == oss)) // stream owner?
release_stream(oss->stream);
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,24 +787,42 @@ 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;
}
len = snprintf(buf, sizeof(buf),
"v=0\r\n"
"o=- 5678901234 1 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",
con->sadr_ip,
con->os->dvbs2num,
con->os->dvbtnum + con->os->dvbt2num,
con->os->dvbcnum + con->os->dvbc2num
);
if (con->os->dvbtnum + con->os->dvbt2num + con->os->dvbcnum + con->os->dvbc2num)
len = snprintf(buf, sizeof(buf),
"v=0\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",
con->sadr_ip,
con->os->dvbs2num,
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"
"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);
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++)
op->pid[i] = p->pid[i];
if (p->set & (1UL << PARAM_APID))
for (i = 0 ; i < 1024 ; i++)
op->pid[i] |= p->pid[i];
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++)
op->pid[i] &= ~p->dpid[i];
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,7 +1391,11 @@ static int setup_session(struct oscon *con, int newtrans)
if (!str)
return -500;
merge_pids(sp, p);
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 (os->has_switch)
update_switch_vec(sess);
if (!sess->mccs.lh_first)
stop_session(sess);
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;
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);
proc_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;
}
dump(buf, len);
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;
@ -2517,24 +2634,27 @@ static void awrite(char *fn, char *txt)
int main(int argc, char **argv)
{
int nodms = 0, nossdp = 0, nodvbt = 0, vlan = 0, noswitch = 0;
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;

View File

@ -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
@ -305,7 +310,7 @@ struct ossess {
uint32_t timeout_len;
time_t timeout;
int nsfd;
struct ostrans trans;
struct dvb_params p;
@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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