int tune(int aid, int sid) { adapter *ad = get_adapter(aid); int rv = 0; SPid *p; if (!ad) return -400; mutex_lock(&ad->mutex); ad->last_sort = getTick(); if (sid == ad->master_sid && ad->do_tune) { ad->tp.switch_type = ad->switch_type; ad->tp.uslot = ad->uslot; ad->tp.ufreq = ad->ufreq; ad->tp.pin = ad->pin; ad->tp.committed_no = ad->committed_no; ad->tp.uncommitted_no = ad->uncommitted_no; rv = ad->tune(ad->id, &ad->tp); ad->status = 0; ad->status_cnt = 0; set_socket_pos(ad->sock, 0); // flush the existing buffer ad->rlen = 0; if (ad->sid_cnt > 1) // the master changed the frequency { close_streams_for_adapter(aid, sid); if (update_pids(aid)) { mutex_unlock(&ad->mutex); return -503; } } #ifdef TABLES_H p = find_pid(aid, 0); if (!p || p->flags == 3) // add pid 0 if not explicitly added { LOG( "Adding pid 0 to the list of pids as not explicitly added for adapter %d", aid); mark_pid_add(-1, aid, 0); } #endif } else LOG("not tuning for SID %d (do_tune=%d, master_sid=%d)", sid, ad->do_tune, ad->master_sid); if (rv < 0) mark_pids_deleted(aid, sid, NULL); if (update_pids(aid)) { mutex_unlock(&ad->mutex); return -503; } mutex_unlock(&ad->mutex); return rv; }
// avoid adapter close unless all the adapters can be closed int adapter_timeout(sockets *s) { int do_close = 1, i, max_close = 0; int rtime = getTick(); adapter *ad = get_adapter(s->sid); if (!ad) return 1; if (ad->force_close) return 1; if (get_streams_for_adapter(ad->id) > 0) { ad->rtime = getTick(); s->rtime = ad->rtime; LOG("Keeping the adapter %d open as there are active streams", ad->id); return 0; } for (i = 0; i < MAX_ADAPTERS; i++) if ((ad = get_adapter_nw(i))) { if (rtime - ad->rtime < s->close_sec) do_close = 0; if (ad && max_close < ad->rtime) max_close = ad->rtime; } LOG("Requested adapter %d close due to timeout, result %d max_rtime %d", s->sid, do_close, max_close); if (!do_close) s->rtime = max_close; return do_close; }
void mark_pids_deleted(int aid, int sid, char *pids) //pids==NULL -> delete all pids { int i, la, pid; adapter *ad; char *arg[MAX_PIDS]; ad = get_adapter(aid); if (!ad) return; LOG("deleting pids on adapter %d, sid %d, pids=%s", aid, sid, pids ? pids : "NULL"); if (pids) { la = split(arg, pids, MAX_PIDS, ','); for (i = 0; i < la; i++) { pid = map_int(arg[i], NULL); mark_pid_deleted(aid, sid, pid, NULL); } return; } for (i = 0; i < MAX_PIDS; i++) mark_pid_deleted(aid, sid, ad->pids[i].pid, &ad->pids[i]); // if(sid == -1) // reset_pids_type(aid); dump_pids(aid); }
void dump_pids(int aid) { int i, dp = 1; if (!opts.log) return; adapter *p = get_adapter(aid); if (!p) return; for (i = 0; i < MAX_PIDS; i++) if (p->pids[i].flags > 0) { if (dp) LOGL(2, "Dumping pids table for adapter %d, pid errors %d", aid, p->pid_err - p->dec_err); dp = 0; LOGL(2, "pid %d, fd %d, type %d packets %d, d/c errs %d/%d, flags %d, key %d, sids: %d %d %d %d %d %d %d %d", p->pids[i].pid, p->pids[i].fd, p->pids[i].type, p->pids[i].cnt, p->pids[i].dec_err, p->pids[i].err, p->pids[i].flags, p->pids[i].key, p->pids[i].sid[0], p->pids[i].sid[1], p->pids[i].sid[2], p->pids[i].sid[3], p->pids[i].sid[4], p->pids[i].sid[5], p->pids[i].sid[6], p->pids[i].sid[7]); } }
int netcv_del_pid(int fd, int pid) { //fprintf(stderr, "REEL: netcv_del_pid (id=%d, pid=%d)\n", fd, pid); int i, hit = 0; adapter *ad; fd -= 100; ad = get_adapter(fd); if (!ad) return 0; LOGL(3, "netceiver: del_pid for aid %d, pid %d, err %d", fd, pid, SN.err); if (SN.err) // error reported, return error return 0; for(i = 0; i < MAX_PIDS; i++) if (SN.npid[i] == pid || hit) { SN.npid[i] = SN.npid[i + 1]; hit = 1; } if (hit && sn[fd].lp > 0) sn[fd].lp--; SN.want_commit = 1; return 0; }
int mark_pids_add(int sid, int aid, char *pids) { int i, la; adapter *ad; char *arg[MAX_PIDS + 2]; int pid; ad = get_adapter(aid); if (!ad) return -1; if (!pids) return -1; LOG("adding pids to adapter %d, sid %d, pids=%s", aid, sid, pids ? pids : "NULL"); la = split(arg, pids, MAX_PIDS, ','); for (i = 0; i < la; i++) { pid = map_intd(arg[i], NULL, -1); if (pid == -1) continue; if (mark_pid_add(sid, aid, pid) < 0) return -1; } dump_pids(aid); return 0; }
void close_adapter_for_stream(int sid, int aid) { adapter *ad; if (!(ad = get_adapter(aid))) return; mutex_lock(&ad->mutex); if (ad->master_sid == sid) { ad->master_sid = -1; fix_master_sid(aid); } if (ad->sid_cnt > 0) ad->sid_cnt--; else mark_pids_deleted(aid, -1, NULL); LOG("closed adapter %d for stream %d m:%d s:%d", aid, sid, ad->master_sid, ad->sid_cnt); // delete the attached PIDs as well mark_pids_deleted(aid, sid, NULL); update_pids(aid); // if (a[aid]->sid_cnt == 0) // close_adapter (aid); mutex_unlock(&ad->mutex); }
int update_pids(int aid) { int i, dp = 1; adapter *ad; ad = get_adapter(aid); if (!ad) return 0; #ifdef TABLES_H for (i = 0; i < MAX_PIDS; i++) if ((ad->pids[i].flags == 3)) tables_pid_del(ad, ad->pids[i].pid); #endif for (i = 0; i < MAX_PIDS; i++) if ((ad->pids[i].flags == 3)) { if (dp) dump_pids(aid); dp = 0; ad->pids[i].flags = 0; if (ad->pids[i].fd > 0) ad->del_filters(ad->pids[i].fd, ad->pids[i].pid); ad->pids[i].fd = 0; ad->pids[i].type = 0; ad->pids[i].filter = ad->pids[i].key = 255; ad->pids[i].csid = 0; ad->pids[i].version = -1; ad->pids[i].enabled_channels = 0; } for (i = 0; i < MAX_PIDS; i++) if (ad->pids[i].flags == 2) { if (dp) dump_pids(aid); dp = 0; if (ad->pids[i].fd <= 0) if ((ad->pids[i].fd = ad->set_pid(ad, ad->pids[i].pid)) < 0) { request_adapter_close(ad); return 1; // error } ad->pids[i].flags = 1; if (ad->pids[i].pid == 0) ad->pat_processed = 0; ad->pids[i].cnt = 0; ad->pids[i].cc = 255; ad->pids[i].err = 0; ad->pids[i].dec_err = 0; ad->pids[i].version = -1; ad->pids[i].csid = -1; } ad->commit(ad); return 0; }
/** * Remove adapter path from list */ static void remove_adapter(const char *path) { adapter_object *a = get_adapter(path); if (a) { g_free(a->path); g_object_unref(a->proxy); g_free(a); llist_remove(adapters(), a); } }
int mark_pid_add(int sid, int aid, int _pid) { adapter *ad; int k, i; ad = get_adapter(aid); int found = 0; SPid *p; if (!ad) return 1; // check if the pid already exists, if yes add the sid if ((p = find_pid(aid, _pid))) { LOG("found already existing pid %d flags %d", _pid, p->flags); for (k = 0; k < MAX_STREAMS_PER_PID; k++) if (p->sid[k] == -1 || p->sid[k] == sid) { if (p->flags == 3) p->flags = 2; p->sid[k] = sid; found = 1; break; } if (!found) { LOG("too many streams for PID %d adapter %d", _pid, aid); return -1; } #ifdef TABLES_H tables_pid_add(ad, _pid, 1); #endif return 0; } // add the new pid in a new position for (i = 0; i < MAX_PIDS; i++) if (ad->pids[i].flags <= 0) { ad->pids[i].flags = 2; ad->pids[i].pid = _pid; ad->pids[i].sid[0] = sid; ad->pids[i].filter = ad->pids[i].key = ad->pids[i].ecm_parity = 255; #ifdef TABLES_H tables_pid_add(ad, _pid, 0); #endif return 0; } LOG("MAX_PIDS (%d) reached for adapter %d in adding PID: %d", MAX_PIDS, aid, _pid); dump_pids(aid); dump_adapters(); return -1; }
SPid *find_pid(int aid, int p) { int i; adapter *ad = get_adapter(aid); if (!ad) return NULL; for (i = 0; i < MAX_PIDS; i++) if ((ad->pids[i].flags > 0) && (ad->pids[i].pid == p)) return &ad->pids[i]; return NULL; }
/** * Add adapter to list */ static void add_adapter(const char *path, DBusGProxy *proxy) { adapter_object *a; if (get_adapter(path)) remove_adapter(path); a = (adapter_object *) g_new(adapter_object, 1); a->path = g_strdup(path); a->proxy = proxy; llist_add(adapters(), a); }
int satipc_timeout(sockets *s) { adapter *ad = get_adapter(s->sid); LOG( "satipc: Sent keep-alive to the satip server %s:%d, adapter %d, socket_id %d, handle %d, timeout %d", ad?ad->sip:NULL, ad ? ad->sport : 0, s->sid, s->id, s->sock, s->close_sec); if (!ad) return 1; http_request(ad, NULL, "OPTIONS"); s->rtime = getTick(); return 0; }
int netcv_tune(int aid, transponder * tp) { //fprintf(stderr, "REEL: netcv_tune (id=%d, tp.freq=%d)\n", aid, tp->freq); adapter *ad = get_adapter(aid); if (!ad) return 1; if (tp->sys == SYS_DVBT) LOGL(0, "netceiver: Sorry, DVB-T not yet implemented"); SN.want_tune = 1; // we do not tune right now, just set the flag for netcv_commit SN.want_commit = 0; SN.lp = 0; // make sure number of active pids is 0 after tuning return 0; }
int set_adapter_for_stream(int sid, int aid) { adapter *ad; if (!(ad = get_adapter(aid))) return -1; mutex_lock(&ad->mutex); if (ad->master_sid == -1) ad->master_sid = sid; ad->sid_cnt++; LOG("set adapter %d for stream %d m:%d s:%d", aid, sid, ad->master_sid, ad->sid_cnt); mutex_unlock(&ad->mutex); return 0; }
int get_free_adapter(int freq, int pol, int msys, int src) { int i; adapter *ad; init_all_hw(); i = (src > 0) ? src - 1 : 0; ad = get_adapter(i); if (ad) LOG("get free adapter %d - a[%d] => e:%d m:%d sid_cnt:%d f:%d pol=%d", src - 1, i, ad->enabled, ad->master_sid, ad->sid_cnt, ad->tp.freq, ad->tp.pol) else LOG("get free adapter %d msys %s", i, get_delsys(i)); if (src > 0) { if (ad) { if (ad->sid_cnt == 0 && delsys_match(ad, msys)) return i; if (ad->tp.freq == freq && delsys_match(ad, msys)) return i; } } for (i = 0; i < MAX_ADAPTERS; i++) //first free adapter that has the same msys if ((ad = get_adapter_nw(i)) && ad->sid_cnt == 0 && delsys_match(ad, msys)) return i; for (i = 0; i < MAX_ADAPTERS; i++) if ((ad = get_adapter_nw(i)) && a[i]->tp.freq == freq && delsys_match(ad, msys)) { if ((msys == SYS_DVBS2 || msys == SYS_DVBS) && ad->tp.pol == pol) return i; else return i; } LOG("no adapter found for f:%d pol:%d msys:%d", freq, pol, msys); dump_adapters(); return -1; }
int satipc_rtcp_reply(sockets * s) { unsigned char *b = s->buf, *ver, *signal; char *tun; int i, rlen = s->rlen; adapter *ad = get_adapter(s->sid); int strength, status, snr; uint32_t rp; if (!ad) return 0; // LOG("satip_rtcp_reply called"); if (b[0] == 0x80 && b[1] == 0xC8) { copy32r(rp, b, 20); if ((++ad->repno % 100) == 0) //every 20s LOG( "satipc: rtp report, adapter %d: rtcp missing packets %d, rtp missing %d, rtp ooo %d, pid err %d", ad->id, rp - ad->rcvp, ad->rtp_miss, ad->rtp_ooo, ad->pid_err - ad->dec_err); } for (i = 0; i < rlen - 4; i++) if (b[i] == 'v' && b[i + 1] == 'e' && b[i + 2] == 'r' && b[i + 3] == '=') { ver = b + i; tun = strstr((const char*) ver, "tuner="); if (tun) signal = strchr(tun, ','); if (signal) { sscanf(signal + 1, "%d,%d,%d", &strength, &status, &snr); if (ad->strength != strength && ad->snr != snr) LOGL(3, "satipc: Received signal status from the server for adapter %d, stength=%d status=%d snr=%d", ad->id, strength, status, snr); ad->strength = strength; ad->status = status ? FE_HAS_LOCK : 0; ad->snr = snr; } } return 0; }
/* * Print adapter configuration information * * Arguments: * si pointer to a struct air_cfg_rsp * * Returns: * none * */ void print_cfg_info(struct air_cfg_rsp *si) { const char *adapter, *bus, *media, *vendor; /* * Print a header if it hasn't been done yet. */ if (!cfg_hdr) { printf(CFG_HDR); cfg_hdr = 1; } /* * Format the vendor name and adapter type */ vendor = get_vendor(si->acp_vendor); adapter = get_adapter(si->acp_device); /* * Format the communications medium */ media = get_media_type(si->acp_media); bus = get_bus_type(si->acp_bustype); /* * Print the ARP server information */ printf("%-8s %-8s %-8s %-14s %-4s %ld\n", si->acp_intf, vendor, adapter, media, bus, si->acp_serial); printf(" MAC address = %s\n", format_mac_addr(&si->acp_macaddr)); printf(" Hardware version = %s\n", si->acp_hard_vers); printf(" Firmware version = %s\n", si->acp_firm_vers); }
int set_adapter_parameters(int aid, int sid, transponder * tp) { adapter *ad = get_adapter(aid); if (!ad) return -1; LOG("setting DVB parameters for adapter %d - master_sid %d sid %d old f:%d", aid, ad->master_sid, sid, ad->tp.freq); mutex_lock(&ad->mutex); if (ad->master_sid == -1) ad->master_sid = sid; // master sid was closed ad->do_tune = 0; if (tp->freq != ad->tp.freq || tp->plp != ad->tp.plp || tp->diseqc != ad->tp.diseqc || (tp->pol > 0 && tp->pol != ad->tp.pol) || (tp->sr > 1000 && tp->sr != ad->tp.sr) || (tp->mtype > 0 && tp->mtype != ad->tp.mtype)) { if (sid != ad->master_sid) // slave sid requesting to tune to a different frequency { mutex_unlock(&ad->mutex); LOG( "secondary stream requested tune, not gonna happen\n ad: f:%d sr:%d pol:%d plp:%d src:%d mod %d\n \ new: f:%d sr:%d pol:%d plp:%d src:%d mod %d", ad->tp.freq, ad->tp.sr, ad->tp.pol, ad->tp.plp, ad->tp.diseqc, ad->tp.mtype, tp->freq, tp->sr, tp->pol, tp->plp, tp->diseqc, tp->mtype); return -1; } mark_pids_deleted(aid, -1, NULL); if (update_pids(aid)) { mutex_unlock(&ad->mutex); return -1; } ad->do_tune = 1; }
/** * Disconnects adapter signals */ static void disconnect_adapter(const char *path) { adapter_object *a = get_adapter(path); gboolean dirty; device_object *d; if (!a) return; DEBUG("Disconnecting adapter: %s", path); dbus_g_proxy_disconnect_signal(a->proxy, "DeviceCreated", G_CALLBACK(device_created), NULL); dbus_g_proxy_disconnect_signal(a->proxy, "DeviceRemoved", G_CALLBACK(device_removed), NULL); // Disconnect devices related to this adapter do { dirty = FALSE; LinkedNode *i = devices()->first; while (i) { d = i->element; if (strcmp(d->adapter, path) == 0) { disconnect_device_signals(d->path); dirty = TRUE; break; } i = i->next; } } while (dirty); remove_adapter(path); }
int dvb_tune(int aid, transponder * tp) { int bclear, bpol, iProp = 0; adapter *ad = get_adapter(aid); int fd_frontend = ad->fe; int freq = tp->freq; struct dtv_property p_cmd[20]; struct dtv_properties p = { .num = 0, .props = p_cmd }; struct dvb_frontend_event ev; struct dtv_property p_clear[] = { { .cmd = DTV_CLEAR }, }; struct dtv_properties cmdseq_clear = { .num = 1, .props = p_clear }; memset(p_cmd, 0, sizeof(p_cmd)); bclear = getTick(); if ((ioctl(fd_frontend, FE_SET_PROPERTY, &cmdseq_clear)) == -1) { LOG("FE_SET_PROPERTY DTV_CLEAR failed for fd %d: %s", fd_frontend, strerror(errno)); // return -1; } switch (tp->sys) { case SYS_DVBS: case SYS_DVBS2: bpol = getTick(); freq = setup_switch(fd_frontend, tp); if (freq < MIN_FRQ_DVBS || freq > MAX_FRQ_DVBS) LOG_AND_RETURN(-404, "Frequency %d is not within range ", freq) ADD_PROP(DTV_SYMBOL_RATE, tp->sr) ADD_PROP(DTV_INNER_FEC, tp->fec) ADD_PROP(DTV_PILOT, tp->plts) ADD_PROP(DTV_ROLLOFF, tp->ro) ADD_PROP(DTV_STREAM_ID, tp->plp) LOG( "tuning to %d(%d) pol: %s (%d) sr:%d fec:%s delsys:%s mod:%s rolloff:%s pilot:%s, ts clear=%d, ts pol=%d", tp->freq, freq, get_pol(tp->pol), tp->pol, tp->sr, fe_fec[tp->fec], fe_delsys[tp->sys], fe_modulation[tp->mtype], fe_rolloff[tp->ro], fe_pilot[tp->plts], bclear, bpol) break; case SYS_DVBT: case SYS_DVBT2: if (tp->freq < MIN_FRQ_DVBT || tp->freq > MAX_FRQ_DVBT) LOG_AND_RETURN(-404, "Frequency %d is not within range ", tp->freq) freq = freq * 1000; ADD_PROP(DTV_BANDWIDTH_HZ, tp->bw) ADD_PROP(DTV_CODE_RATE_HP, tp->fec) ADD_PROP(DTV_CODE_RATE_LP, tp->fec) ADD_PROP(DTV_GUARD_INTERVAL, tp->gi) ADD_PROP(DTV_TRANSMISSION_MODE, tp->tmode) ADD_PROP(DTV_HIERARCHY, HIERARCHY_AUTO) ADD_PROP(DTV_STREAM_ID, tp->plp & 0xFF) LOG( "tuning to %d delsys: %s bw:%d inversion:%s mod:%s fec:%s guard:%s transmission: %s, ts clear = %d", freq, fe_delsys[tp->sys], tp->bw, fe_specinv[tp->inversion], fe_modulation[tp->mtype], fe_fec[tp->fec], fe_gi[tp->gi], fe_tmode[tp->tmode], bclear) break; case SYS_DVBC2: case SYS_DVBC_ANNEX_A: if (tp->freq < MIN_FRQ_DVBC || tp->freq > MAX_FRQ_DVBC) LOG_AND_RETURN(-404, "Frequency %d is not within range ", tp->freq) freq = freq * 1000; ADD_PROP(DTV_SYMBOL_RATE, tp->sr) ADD_PROP(DTV_STREAM_ID, ((tp->ds & 0xFF) << 8) | (tp->plp & 0xFF)) // valid for DD DVB-C2 devices LOG("tuning to %d sr:%d specinv:%s delsys:%s mod:%s ts clear =%d", freq, tp->sr, fe_specinv[tp->inversion], fe_delsys[tp->sys], fe_modulation[tp->mtype], bclear) break; case SYS_ATSC: case SYS_DVBC_ANNEX_B: if (tp->freq < MIN_FRQ_DVBC || tp->freq > MAX_FRQ_DVBC) LOG_AND_RETURN(-404, "Frequency %d is not within range ", tp->freq) if (tp->mtype == 0) tp->mtype = QAM_AUTO; freq = freq * 1000; LOG("tuning to %d delsys:%s mod:%s specinv:%s ts clear=%d", freq, fe_delsys[tp->sys], fe_modulation[tp->mtype], fe_specinv[tp->inversion], bclear) break; case SYS_ISDBT: if (tp->freq < MIN_FRQ_DVBT || tp->freq > MAX_FRQ_DVBT) LOG_AND_RETURN(-404, "Frequency %d is not within range ", tp->freq) freq = freq * 1000; ADD_PROP(DTV_ISDBT_PARTIAL_RECEPTION, 0) ADD_PROP(DTV_BANDWIDTH_HZ, tp->bw) // ADD_PROP(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1); // ADD_PROP(DTV_ISDBT_LAYER_ENABLED, 1); LOG("tuning to %d delsys: %s bw:%d inversion:%s , ts clear = %d", freq, fe_delsys[tp->sys], tp->bw, fe_specinv[tp->inversion], bclear) ; break; default: LOG("tuninng to unknown delsys: %s freq %s ts clear = %d", freq, fe_delsys[tp->sys], bclear) break; } ADD_PROP(DTV_FREQUENCY, freq) ADD_PROP(DTV_INVERSION, tp->inversion) ADD_PROP(DTV_MODULATION, tp->mtype); ADD_PROP(DTV_DELIVERY_SYSTEM, tp->sys); ADD_PROP(DTV_TUNE, 0) p.num = iProp; /* discard stale QPSK events */ while (1) { if (ioctl(fd_frontend, FE_GET_EVENT, &ev) == -1) break; } if ((ioctl(fd_frontend, FE_SET_PROPERTY, &p)) == -1) if (ioctl(fd_frontend, FE_SET_PROPERTY, &p) == -1) { perror("FE_SET_PROPERTY TUNE failed"); LOG("set property failed"); return -404; } return 0; } int dvb_set_pid(adapter *a, uint16_t i_pid) { char buf[100]; int fd; int hw, ad; hw = a->pa; ad = a->fn; if (i_pid > 8192) LOG_AND_RETURN(-1, "pid %d > 8192 for /dev/dvb/adapter%d/demux%d", i_pid, hw, ad); sprintf(buf, "/dev/dvb/adapter%d/demux%d", hw, ad); if ((fd = open(buf, O_RDWR | O_NONBLOCK)) < 0) { LOG("Could not open demux device /dev/dvb/adapter%d/demux%d: %s ", hw, ad, strerror (errno)); return -1; } struct dmx_pes_filter_params s_filter_params; memset(&s_filter_params, 0, sizeof(s_filter_params)); s_filter_params.pid = i_pid; s_filter_params.input = DMX_IN_FRONTEND; s_filter_params.output = DMX_OUT_TS_TAP; s_filter_params.flags = DMX_IMMEDIATE_START; s_filter_params.pes_type = DMX_PES_OTHER; if (ioctl(fd, DMX_SET_PES_FILTER, &s_filter_params) < 0) { int pids[MAX_PIDS]; int ep; ep = get_enabled_pids(a, (int *) pids, MAX_PIDS); LOG("failed setting filter on %d (%s), enabled pids %d", i_pid, strerror (errno), ep); return -1; } LOG("setting filter on PID %d for fd %d", i_pid, fd); return fd; }
int satipc_reply(sockets * s) { int rlen = s->rlen; adapter *ad; char *arg[50], *sess, *es, *sid; int la, i, rc; s->rlen = 0; LOG("satipc_reply (sock %d) handle %d, adapter %d:\n%s", s->id, s->sock, s->sid, s->buf); if (!(ad = get_adapter(s->sid))) return 0; sess = strstr(s->buf, "Session:"); la = split(arg, (char *) s->buf, 50, ' '); rc = map_int(arg[1], NULL); if (ad->last_cmd == RTSP_OPTIONS && !sess && ad->session[0]) rc = 454; if (rc == 454 || rc == 503 || rc == 405) { ad->sent_transport = 0; ad->want_tune = 1; ad->want_commit = 1; ad->force_commit = 1; } else if (rc != 200) ad->err = 1; sid = NULL; if (rc == 200 && !ad->want_tune) ad->ignore_packets = 0; sess = NULL; for (i = 0; i < la; i++) if (strncasecmp("Session:", arg[i], 8) == 0) sess = header_parameter(arg, i); else if (strncasecmp("com.ses.streamID:", arg[i], 17) == 0) sid = header_parameter(arg, i); else if (strncasecmp("Server:", arg[i], 7) == 0) { char *ua = header_parameter(arg, i); if (!strncmp(ua, app_name, strlen(app_name))) { ad->satip_addpids = 1; ad->satip_setup_pids = 1; } } if (!ad->err && !ad->session[0] && sess) { if ((es = strchr(sess, ';'))) *es = 0; strncpy(ad->session, sess, sizeof(ad->session)); ad->session[sizeof(ad->session) - 1] = 0; LOG("satipc: session set for adapter %d to %s", ad->id, ad->session); if (sid && ad->stream_id == -1) ad->stream_id = map_int(sid, NULL); ad->expect_reply = 0; ad->force_commit = 1; // http_request(ad, NULL, "PLAY"); satipc_commit(ad); return 0; } if (ad->wp >= ad->qp) ad->expect_reply = 0; else { char *np = (char *) getItem(MAKE_ITEM(ad->id, ad->wp)); if (np) { int len = strlen(np); if (ad->session[0] && !strstr(np, "Session:")) sprintf(np + len - 2, "Session: %s\r\n\r\n", ad->session); LOG("satipc_reply: sending next packet:\n%s", np); write(s->sock, np, strlen(np)); delItem(MAKE_ITEM(ad->id, ad->wp++)); } } if (!ad->expect_reply && (ad->wp >= ad->qp) && (ad->want_commit || ad->force_commit)) // we do not expect reply and no other events in the queue, we commit a { satipc_commit(ad); } return 0; }