static cmyth_conn_t cmyth_conn_connect(char *server, unsigned short port, unsigned buflen, int tcp_rcvbuf, int event) { cmyth_conn_t conn; char announcement[256]; unsigned long tmp_ver; int attempt = 0; top: conn = cmyth_connect(server, port, buflen, tcp_rcvbuf); if (!conn) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_connect(%s, %d, %d) failed\n", __FUNCTION__, server, port, buflen); return NULL; } /* * Find out what the Myth Protocol Version is for this connection. * Loop around until we get agreement from the server. */ if (attempt == 0) tmp_ver = conn->conn_version; conn->conn_version = tmp_ver; if (tmp_ver >= 62) { myth_protomap_t *map = protomap; while (map->version != 0 && map->version != tmp_ver) map++; if (map->version == 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: failed to connect with any version\n", __FUNCTION__); goto shut; } sprintf(announcement, "MYTH_PROTO_VERSION %ld %04X", conn->conn_version, map->token); } else { sprintf(announcement, "MYTH_PROTO_VERSION %ld", conn->conn_version); } if (cmyth_send_message(conn, announcement) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_send_message('%s') failed\n", __FUNCTION__, announcement); goto shut; } if (cmyth_rcv_version(conn, &tmp_ver) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_version() failed\n", __FUNCTION__); goto shut; } cmyth_dbg(CMYTH_DBG_ERROR, "%s: asked for version %ld, got version %ld\n", __FUNCTION__, conn->conn_version, tmp_ver); if (conn->conn_version != tmp_ver) { if (attempt == 1) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: failed to connect with any version\n", __FUNCTION__); goto shut; } attempt = 1; ref_release(conn); goto top; } cmyth_dbg(CMYTH_DBG_PROTO, "%s: agreed on Version %ld protocol\n", __FUNCTION__, conn->conn_version); sprintf(announcement, "ANN Playback %s %d", my_hostname, event); if (cmyth_send_message(conn, announcement) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_send_message('%s') failed\n", __FUNCTION__, announcement); goto shut; } if (cmyth_rcv_okay(conn, "OK") < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_okay() failed\n", __FUNCTION__); goto shut; } return conn; shut: ref_release(conn); return NULL; }
static cmyth_conn_t cmyth_conn_connect(char *server, unsigned short port, unsigned buflen, int tcp_rcvbuf, int event) { cmyth_conn_t conn; char announcement[256]; unsigned long tmp_ver; int attempt = 0; top: conn = cmyth_connect(server, port, buflen, tcp_rcvbuf); if (!conn) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_connect(%s, %d, %d) failed\n", __FUNCTION__, server, port, buflen); return NULL; } /* * Find out what the Myth Protocol Version is for this connection. * Loop around until we get agreement from the server. */ if (attempt == 0) tmp_ver = conn->conn_version; conn->conn_version = tmp_ver; /* * Myth 0.23.1 (Myth 0.23 + fixes) introduced an out of sequence protocol version number (23056) * due to the next protocol version number having already been bumped in trunk. * * http://www.mythtv.org/wiki/Myth_Protocol */ if (tmp_ver >= 62 && tmp_ver != 23056) { // Treat protocol version number 23056 the same as protocol 56 myth_protomap_t *map = protomap; while (map->version != 0 && map->version != tmp_ver) map++; if (map->version == 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: failed to connect with any version\n", __FUNCTION__); goto shut; } sprintf(announcement, "MYTH_PROTO_VERSION %ld %s", conn->conn_version, map->token); } else { sprintf(announcement, "MYTH_PROTO_VERSION %ld", conn->conn_version); } if (cmyth_send_message(conn, announcement) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_send_message('%s') failed\n", __FUNCTION__, announcement); goto shut; } if (cmyth_rcv_version(conn, &tmp_ver) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_version() failed\n", __FUNCTION__); goto shut; } cmyth_dbg(CMYTH_DBG_ERROR, "%s: asked for version %ld, got version %ld\n", __FUNCTION__, conn->conn_version, tmp_ver); if (conn->conn_version != tmp_ver) { if (attempt == 1) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: failed to connect with any version\n", __FUNCTION__); goto shut; } attempt = 1; ref_release(conn); goto top; } cmyth_dbg(CMYTH_DBG_PROTO, "%s: agreed on Version %ld protocol\n", __FUNCTION__, conn->conn_version); sprintf(announcement, "ANN Playback %s %d", my_hostname, event); if (cmyth_send_message(conn, announcement) < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_send_message('%s') failed\n", __FUNCTION__, announcement); goto shut; } if (cmyth_rcv_okay(conn, "OK") < 0) { cmyth_dbg(CMYTH_DBG_ERROR, "%s: cmyth_rcv_okay() failed\n", __FUNCTION__); goto shut; } /* * All of the downstream code in libcmyth assumes a monotonically increasing version number. * This was not the case for Myth 0.23.1 (0.23 + fixes) where protocol version number 23056 * was used since 57 had already been used in trunk. * * Convert from protocol version number 23056 to version number 56 so subsequent code within * libcmyth uses the same logic for the 23056 protocol as would be used for protocol version 56. */ if (conn->conn_version == 23056) { conn->conn_version = 56; } return conn; shut: ref_release(conn); return NULL; }