static GstRTSPResult
new_tcp (GstRTSPWFDClient * client)
{
- int fd;
GstRTSPResult res = GST_RTSP_OK;
GstRTSPConnection *conn = NULL;
GstRTSPConnection *parent_conn = NULL;
GstRTSPUrl *url;
- struct sockaddr_in server_addr;
- socklen_t sin_len;
GSource *source;
GMainContext *context;
- int retry = 0;
- int bsize = 1024000;
- int rn = sizeof(int);
- int state = 1;
- GSocket *tcp = NULL;
+ int conn_retry_remained = 10;
+ int bsize = -1;
+ GError *err = NULL;
- struct sockaddr_in my_addr;
/* client's address */
- gint sockoptval = 1;
int ret;
- GSocketAddress *local;
+ GSocket *tcp_socket = NULL;
+ GSocketAddress *tcp_socket_addr = NULL;
/* Get the client connection details */
parent_conn = gst_rtsp_client_get_connection (GST_RTSP_CLIENT (client));
GST_INFO ("create new connection %p ip %s:%d", client, url->host, url->port);
/* create a TCP/IP socket */
- if ((tcp = g_socket_new (AF_INET, SOCK_STREAM, 0, NULL)) == NULL) {
+ if ((tcp_socket = g_socket_new (G_SOCKET_FAMILY_IPV4, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_TCP, NULL)) == NULL) {
GST_ERROR ("cannot create socket");
return GST_RTSP_ERROR;
}
+
/* allow immediate reuse of the port */
- ret = g_socket_set_option (tcp, SOL_SOCKET, SO_REUSEADDR, sockoptval, NULL);
- if(ret == 0)
- {
+ ret = g_socket_set_option (tcp_socket, SOL_SOCKET, SO_REUSEADDR, TRUE, NULL);
+ if (ret == 0) {
GST_ERROR ("cannot change socket options");
- return GST_RTSP_ERROR;
+ goto failed;
}
- /* bind the socket to our source address */
- memset ((char*)&my_addr, 0, sizeof(my_addr));
- /* 0 out the structure */
- my_addr.sin_family = AF_INET;
- /* address family */
- my_addr.sin_port = htons (url->port);
- my_addr.sin_addr.s_addr = inet_addr(url->host);
-
- local = g_socket_address_new_from_native (&my_addr, sizeof(my_addr));
-
- g_socket_set_blocking (tcp, FALSE);
-
-tcp_retry:
- if ((g_socket_connect (tcp, local, NULL, NULL))) {
- char buf[255] = {0, };
- strerror_r (errno, buf, sizeof(buf));
- g_print( "Error connecting socket : %s\n", buf );
- if (retry < 50) {
- GST_ERROR("Connection failed... Try again...");
- usleep(100000);
- retry++;
- goto tcp_retry;
- }
- return GST_RTSP_ERROR;
+ /* bind the socket to our source address */
+ tcp_socket_addr = g_inet_socket_address_new_from_string (url->host, url->port);
+ if (!tcp_socket_addr) {
+ GST_ERROR ("tcp_socket_addr is failed");
+ goto failed;
}
- if ((res = gst_rtsp_connection_create_from_socket (tcp, url->host, url->port, NULL, &conn)) < 0)
- return GST_RTSP_ERROR;
+ g_socket_set_blocking (tcp_socket, FALSE);
- GST_DEBUG_OBJECT (client, "Able to connect to new port");
+ while (!g_socket_connect (tcp_socket, tcp_socket_addr, NULL, &err)) {
+ GST_ERROR ("Connection failed... Try again...");
+ if (err) {
+ GST_ERROR (" error: [%s]", err->message);
+ g_error_free (err);
+ err = NULL;
+ }
- sin_len = sizeof(struct sockaddr);
- fd = g_socket_get_fd (gst_rtsp_connection_get_read_socket (conn));
- if (fd == -1) {
- return GST_RTSP_EINVAL;
+ if (conn_retry_remained-- == 0) {
+ GST_ERROR ("Failed to connection finally.");
+ goto failed;
+ }
+
+ usleep (100000);
}
- if (getsockname (fd, (struct sockaddr *)&server_addr, &sin_len) < 0) {
- GST_ERROR_OBJECT (client, "Getsockname fail");
- close(fd);
- return GST_RTSP_ERROR;
+ res = gst_rtsp_connection_create_from_socket (tcp_socket, url->host, url->port, NULL, &conn);
+ if (res < 0) {
+ GST_ERROR ("gst_rtsp_connection_create_from_socket function is failed");
+ goto failed;
}
- GST_DEBUG_OBJECT (client, "New port created : %d", ntohs(server_addr.sin_port));
+ /* Set send buffer size to 1024000 */
+ if (g_socket_set_option (tcp_socket , SOL_SOCKET, SO_SNDBUF, 1024000, NULL))
+ GST_DEBUG_OBJECT (client, "Set send buf size : %d\n", bsize);
+ else
+ GST_ERROR_OBJECT (client, "SO_SNDBUF setsockopt failed");
- /* Set send buffer size to 5242880 */
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &bsize, (socklen_t)rn) < 0) {
- GST_ERROR_OBJECT(client, "setsockopt failed");
+ /* Get send buffer size */
+ if (g_socket_get_option (tcp_socket , SOL_SOCKET, SO_SNDBUF, &bsize, &err)) {
+ GST_DEBUG_OBJECT (client, "Get send buf size : %d\n", bsize);
} else {
- if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &bsize, (socklen_t *)&rn) < 0) {
- char buf[256] = {0, };
- strerror_r(errno, buf, sizeof(buf));
- GST_ERROR_OBJECT(client, "getsockopt failed : [%s]", buf);
+ GST_ERROR_OBJECT (client, "SO_SNDBUF getsockopt failed");
+ if (err) {
+ GST_ERROR_OBJECT (client," error: [%s]", err->message);
+ g_error_free (err);
+ err = NULL;
}
- GST_WARNING_OBJECT(client, "New Send buf size : %d\n", bsize);
}
- if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &state, sizeof(state)) < 0) {
- GST_ERROR_OBJECT(client, "setsockopt failed");
- } else {
- GST_WARNING_OBJECT(client, "TCP NO DELAY");
- }
+ /* Set TCP no delay */
+ if (g_socket_set_option (tcp_socket , IPPROTO_TCP, TCP_NODELAY, TRUE, NULL))
+ GST_DEBUG_OBJECT (client, "TCP NO DELAY");
+ else
+ GST_ERROR_OBJECT (client, "TCP_NODELAY setsockopt failed");
client->priv->data_conn = conn;
/* create watch for the connection and attach */
client->priv->datawatch = gst_rtsp_watch_new (client->priv->data_conn, &watch_funcs_tcp, client, (GDestroyNotify) client_watch_notify_tcp);
GST_DEBUG_OBJECT (client, "data watch : %p", client->priv->datawatch);
- /* find the context to add the watch */
- if ((source = g_main_current_source ()))
- context = g_source_get_context (source);
- else
- context = NULL;
-
- GST_DEBUG (" source = %p", source);
- GST_INFO ("attaching to context %p", context);
- client->priv->datawatchid = gst_rtsp_watch_attach (client->priv->datawatch, context);
- gst_rtsp_watch_unref (client->priv->datawatch);
- return res;
+ /* find the context to add the watch */
+ if ((source = g_main_current_source ()))
+ context = g_source_get_context (source);
+ else
+ context = NULL;
+
+ GST_DEBUG (" source = %p", source);
+ GST_INFO ("attaching to context %p", context);
+ client->priv->datawatchid = gst_rtsp_watch_attach (client->priv->datawatch, context);
+ gst_rtsp_watch_unref (client->priv->datawatch);
+ g_object_unref (tcp_socket_addr);
+ return res;
+
+failed:
+ g_object_unref (tcp_socket_addr);
+ g_object_unref (tcp_socket);
+
+ return GST_RTSP_ERROR;
}
static void