diff --git a/ddbridge/ddbridge-hw.c b/ddbridge/ddbridge-hw.c index 3d61ebb..4e83683 100644 --- a/ddbridge/ddbridge-hw.c +++ b/ddbridge/ddbridge-hw.c @@ -557,7 +557,7 @@ static const struct ddb_info ddb_mod_fsm_8 = { static const struct ddb_info ddb_mod_fsm_4 = { .type = DDB_MOD, - .name = "Digital Devices DVB-C modulator FSM-8", + .name = "Digital Devices DVB-C modulator FSM-4", .version = 2, .regmap = &octopus_mod_2_map, .port_num = 4, diff --git a/ddbridge/ddbridge-sx8.c b/ddbridge/ddbridge-sx8.c index 8f062f4..92177d5 100644 --- a/ddbridge/ddbridge-sx8.c +++ b/ddbridge/ddbridge-sx8.c @@ -154,7 +154,8 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status) return stat; } -static int mci_set_tuner(struct dvb_frontend *fe, u32 tuner, u32 on) +static int mci_set_tuner(struct dvb_frontend *fe, u32 tuner, u32 on, + u8 flags, u8 gain) { struct sx8 *state = fe->demodulator_priv; struct mci_base *mci_base = state->mci.base; @@ -164,7 +165,8 @@ static int mci_set_tuner(struct dvb_frontend *fe, u32 tuner, u32 on) memset(&cmd, 0, sizeof(cmd)); cmd.tuner = state->mci.tuner; cmd.command = on ? SX8_CMD_INPUT_ENABLE : SX8_CMD_INPUT_DISABLE; - cmd.sx8_input_enable.flags = sx8_base->gain_mode[state->mci.tuner]; + cmd.sx8_input_enable.flags = flags;//sx8_base->gain_mode[state->mci.tuner]; + cmd.sx8_input_enable.rf_gain = gain; return ddb_mci_cmd(&state->mci, &cmd, NULL); } @@ -187,7 +189,7 @@ static int stop_iq(struct dvb_frontend *fe) mutex_lock(&mci_base->tuner_lock); sx8_base->tuner_use_count[input]--; if (!sx8_base->tuner_use_count[input]) - mci_set_tuner(fe, input, 0); + mci_set_tuner(fe, input, 0, 0, 0); if (state->mci.demod != SX8_DEMOD_NONE) { sx8_base->demod_in_use[state->mci.demod] = 0; state->mci.demod = SX8_DEMOD_NONE; @@ -225,7 +227,7 @@ static int stop(struct dvb_frontend *fe) mutex_lock(&mci_base->tuner_lock); sx8_base->tuner_use_count[input]--; if (!sx8_base->tuner_use_count[input]) - mci_set_tuner(fe, input, 0); + mci_set_tuner(fe, input, 0, 0, 0); if (state->mci.demod != SX8_DEMOD_NONE) { sx8_base->demod_in_use[state->mci.demod] = 0; state->mci.demod = SX8_DEMOD_NONE; @@ -327,7 +329,7 @@ static int start(struct dvb_frontend *fe, u32 flags, u32 modmask, u32 ts_config) state->mci.demod = i; if (!sx8_base->tuner_use_count[input]) - mci_set_tuner(fe, input, 1); + mci_set_tuner(fe, input, 1, 0, 0); sx8_base->tuner_use_count[input]++; sx8_base->iq_mode = (ts_config > 1); unlock: @@ -400,8 +402,10 @@ static int start_iq(struct dvb_frontend *fe, u32 flags, goto unlock; } state->mci.demod = 0; - if (!sx8_base->tuner_use_count[input]) + /* + if (!sx8_base->tuner_use_count[input]) mci_set_tuner(fe, input, 1); + */ sx8_base->tuner_use_count[input]++; sx8_base->iq_mode = (ts_config > 1); unlock: @@ -409,13 +413,14 @@ static int start_iq(struct dvb_frontend *fe, u32 flags, if (stat) return stat; } + mci_set_tuner(fe, input, 1, flags & 0xff, 0); memset(&cmd, 0, sizeof(cmd)); cmd.command = SX8_CMD_START_IQ; - cmd.sx8_start_iq.flags = flags >> 8; + cmd.sx8_start_iq.flags = (flags >> 16) & 0xff; cmd.sx8_start_iq.roll_off = roll_off; cmd.sx8_start_iq.frequency = p->frequency * 1000; cmd.sx8_start_iq.symbol_rate = p->symbol_rate; - cmd.sx8_start_iq.gain = flags & 0xff; + cmd.sx8_start_iq.gain = (flags >> 8) & 0xff; cmd.tuner = state->mci.tuner; cmd.demod = state->mci.demod; stat = ddb_mci_cmd(&state->mci, &cmd, NULL); @@ -479,7 +484,7 @@ static int set_parameters(struct dvb_frontend *fe) state->mci.signal_info.status = MCI_DEMOD_WAIT_SIGNAL; } } else { - stat = start_iq(fe, (isi >> 8) & 0xffff, 4, ts_config); + stat = start_iq(fe, isi & 0xffffff, 4, ts_config); if (!stat) { state->iq_started = 1; state->first_time_lock = 1; diff --git a/lib/src/ca.c b/lib/src/ca.c index 6460758..9c38caa 100644 --- a/lib/src/ca.c +++ b/lib/src/ca.c @@ -14,9 +14,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -66,6 +68,32 @@ int streamsock(const char *port, int family, struct sockaddr *sadr) return sock; } +int unixsock(const char *path) +{ + unlink(path); + + struct sockaddr_un sa; + size_t hlen = offsetof(struct sockaddr_un, sun_path); + size_t pathlen = strlen(path); + if (pathlen > sizeof(sa.sun_path)) + return(-1); + memset(&sa, 0, hlen); + sa.sun_family = AF_UNIX; + if (pathlen > 0) + memcpy(sa.sun_path, path, pathlen); + + int sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock == -1) + return(-1); + + if (bind(sock, (struct sockaddr *) &sa, (socklen_t) (hlen + pathlen)) == -1) { + close(sock); + return(-1); + } + + return(sock); +} + static int ai_callback(void *arg, uint8_t slot_id, uint16_t session_number, uint8_t application_type, uint16_t application_manufacturer, uint16_t manufacturer_code, uint8_t menu_string_length, @@ -357,10 +385,17 @@ static void handle_ci(struct dddvb_ca *ca) int len; int sock, i; struct sockaddr sadr; - char port[6]; + char port[6], path[32]; - snprintf(port, sizeof(port), "%u", (uint16_t) (8888 + ca->nr)); - sock = streamsock(port, AF_INET, &sadr); + if (ca->dd->cam_family == 1) { + snprintf(port, sizeof(port), "%u", (uint16_t) (8888 + ca->nr)); + sock = streamsock(port, AF_INET, &sadr); + } else if (ca->dd->cam_family == 2) { + snprintf(path, sizeof(path), "/var/run/resiplayer/cam%u", ca->nr); + sock = unixsock(path); + } else { + sock = -1; + } if (listen(sock, 4) < 0) { dbgprintf(DEBUG_CA, "listen error"); return; @@ -466,6 +501,8 @@ static int mmi_close_callback(void *arg, uint8_t slot_id, uint16_t snum, struct dddvb_ca *ca = arg; ca->mmi_state = MMI_STATE_CLOSED; + if (ca->dd->cam_proto == 2) + sendstringx(ca->sock, "CLOSE", 0, NULL); return 0; } @@ -492,6 +529,8 @@ static int mmi_display_control_callback(void *arg, uint8_t slot_id, uint16_t snu en50221_app_mmi_display_reply(ca->stdcam->mmi_resource, snum, MMI_DISPLAY_REPLY_ID_MMI_MODE_ACK, &reply); ca->mmi_state = MMI_STATE_OPEN; + if (ca->dd->cam_proto == 2) + sendstringx(ca->sock, "OPEN", 0, NULL); return 0; } @@ -502,7 +541,10 @@ static int mmi_enq_callback(void *arg, uint8_t slot_id, uint16_t snum, struct dddvb_ca *ca = arg; if (ca->sock >= 0) { + if (ca->dd->cam_proto == 1) sendstring(ca->sock, "%.*s: ", text_size, text); + if (ca->dd->cam_proto == 2) + sendstringx(ca->sock, "ENQ", text_size, text); } //mmi_enq_blind = blind_answer; //mmi_enq_length = expected_answer_length; @@ -520,7 +562,7 @@ static int mmi_menu_callback(void *arg, uint8_t slot_id, uint16_t snum, uint32_t i; struct dddvb_ca *ca = arg; - if (ca->sock >= 0) { + if ((ca->sock >= 0) && (ca->dd->cam_proto == 1)) { if (title->text_length) sendstring(ca->sock, "%.*s\n", title->text_length, title->text); if (sub_title->text_length) @@ -530,6 +572,13 @@ static int mmi_menu_callback(void *arg, uint8_t slot_id, uint16_t snum, if (bottom->text_length) sendstring(ca->sock, "%.*s\n", bottom->text_length, bottom->text); } + if (ca->dd->cam_proto == 2) { + sendstringx(ca->sock, "MENU", title->text_length, title->text); + sendstringx(ca->sock, "MSUB", sub_title->text_length, sub_title->text); + for (i = 0; i < item_count; i++) + sendstringx(ca->sock, "ITEM", items[i].text_length, items[i].text); + sendstringx(ca->sock, "MEND", bottom->text_length, bottom->text); + } ca->mmi_state = MMI_STATE_MENU; return 0; } diff --git a/lib/src/dddvb.h b/lib/src/dddvb.h index 4f2390f..a478bb2 100644 --- a/lib/src/dddvb.h +++ b/lib/src/dddvb.h @@ -152,6 +152,9 @@ struct dddvb { struct dddvb_fe dvbfe[DDDVB_MAX_DVB_FE]; struct dddvb_ca dvbca[DDDVB_MAX_DVB_CA]; + unsigned int cam_family; + unsigned int cam_proto; + unsigned int cam_port; unsigned int get_ts:1; }; diff --git a/lib/src/dvb.c b/lib/src/dvb.c index 0304236..586a808 100644 --- a/lib/src/dvb.c +++ b/lib/src/dvb.c @@ -954,6 +954,31 @@ void lnb_config(struct dddvb *dd, char *name, char *val) } } +void ca_config(struct dddvb *dd, char *name, char *val) +{ + if (!name || !val) + return; + char *p = strpbrk(val, "\r\n"); + if (p) + *p = 0; + if (!strcasecmp(name, "family")) { + if (!strcasecmp(val, "tcp")) { + dd->cam_family = 1; + } else if (!strcasecmp(val, "unix")) { + dd->cam_family = 2; + } + return; + } + if (!strcasecmp(name, "proto")) { + dd->cam_proto = strtoul(val, NULL, 10); + return; + } + if (!strcasecmp(name, "port")) { + dd->cam_port = strtoul(val, NULL, 10); + return; + } +} + int dddvb_dvb_init(struct dddvb *dd) { pthread_mutex_init(&dd->uni_lock, 0); @@ -961,6 +986,23 @@ int dddvb_dvb_init(struct dddvb *dd) parse_config(dd, "", "scif", &scif_config); set_lnb(dd, 0, 0, 9750000, 10600000, 11700000); parse_config(dd, "", "LNB", &lnb_config); + parse_config(dd, "", "CA", &ca_config); + { + if (dd->cam_family == 0) + dd->cam_family = 1; + if (dd->cam_proto == 0) { + switch (dd->cam_family) { + case 1: + dd->cam_proto = 1; + break; + case 2: + dd->cam_proto = 2; + break; + } + } + if (dd->cam_port == 0) + dd->cam_port = 8888; + } scan_dvbca(dd); } diff --git a/lib/src/tools.c b/lib/src/tools.c index 4bacb8a..9592095 100644 --- a/lib/src/tools.c +++ b/lib/src/tools.c @@ -4,6 +4,7 @@ #include #include #include +#include int sendlen(int sock, char *buf, int len) @@ -33,6 +34,34 @@ int sendstring(int sock, char *fmt, ...) return len; } +int sendstringx(int sock, const char *label, uint32_t text_length, const uint8_t *text) +{ + if (sock < 0) + return(-1); + + uint8_t buf[strlen(label) + 1 + text_length * 3 + 2]; + + strcpy(buf, label); + int len = strlen(buf); + buf[len++] = 0x20; + while (text_length--) { + int c = *text++; + if (c == 0x5C) { + buf[len++] = 0x5C; + buf[len++] = 0x5C; + } else if ((c < 0x20) || (c > 0x7E)) { + buf[len++] = 0x5C; + snprintf(buf+len, 3, "%02X", c); + len += 2; + } else { + buf[len++] = (uint8_t) c; + } + } + buf[len++] = 0x0A; + sendlen(sock, buf, len); + return(len); +} + time_t mtime(time_t *t) { struct timespec ts; diff --git a/lib/src/tools.h b/lib/src/tools.h index 06c8593..d09916d 100644 --- a/lib/src/tools.h +++ b/lib/src/tools.h @@ -4,5 +4,6 @@ time_t mtime(time_t *t); int sendlen(int sock, char *buf, int len); int sendstring(int sock, char *fmt, ...); +int sendstringx(int sock, const char *label, uint32_t text_length, const uint8_t *text); #endif /* _DDDVB_TOOLS_H_ */