summaryrefslogtreecommitdiffstats
path: root/sys/dvb/camswclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dvb/camswclient.c')
-rw-r--r--sys/dvb/camswclient.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/sys/dvb/camswclient.c b/sys/dvb/camswclient.c
new file mode 100644
index 00000000..d956f3c9
--- /dev/null
+++ b/sys/dvb/camswclient.c
@@ -0,0 +1,162 @@
+/*
+ * camswclient.c - GStreamer softcam client
+ * Copyright (C) 2007 Alessandro Decina
+ *
+ * Authors:
+ * Alessandro Decina <alessandro@nnva.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include <gst/gst.h>
+
+#include "camswclient.h"
+#include "cam.h"
+#include "camutils.h"
+
+#define GST_CAT_DEFAULT cam_debug_cat
+#define UNIX_PATH_MAX 108
+
+CamSwClient *
+cam_sw_client_new ()
+{
+ CamSwClient *client = g_new0 (CamSwClient, 1);
+
+ client->state = CAM_SW_CLIENT_STATE_CLOSED;
+
+ return client;
+}
+
+static void
+reset_state (CamSwClient * client)
+{
+ if (client->sock)
+ close (client->sock);
+
+ if (client->sock_path)
+ g_free (client->sock_path);
+}
+
+void
+cam_sw_client_free (CamSwClient * client)
+{
+ g_return_if_fail (client != NULL);
+
+ if (client->state != CAM_SW_CLIENT_STATE_CLOSED)
+ GST_WARNING ("client not in CLOSED state when free'd");
+
+ reset_state (client);
+ g_free (client);
+}
+
+gboolean
+cam_sw_client_open (CamSwClient * client, const char *sock_path)
+{
+ struct sockaddr_un addr;
+ int ret;
+
+ g_return_val_if_fail (client != NULL, FALSE);
+ g_return_val_if_fail (client->state == CAM_SW_CLIENT_STATE_CLOSED, FALSE);
+ g_return_val_if_fail (sock_path != NULL, FALSE);
+
+ addr.sun_family = AF_UNIX;
+ strncpy (addr.sun_path, sock_path, UNIX_PATH_MAX);
+
+ GST_INFO ("connecting to softcam socket: %s", sock_path);
+ client->sock = socket (PF_UNIX, SOCK_STREAM, 0);
+ ret =
+ connect (client->sock, (struct sockaddr *) &addr,
+ sizeof (struct sockaddr_un));
+ if (ret != 0) {
+ GST_ERROR ("error opening softcam socket %s, error: %s",
+ sock_path, strerror (errno));
+
+ return FALSE;
+ }
+
+ client->sock_path = g_strdup (sock_path);
+ client->state = CAM_SW_CLIENT_STATE_OPEN;
+
+ return TRUE;
+}
+
+void
+cam_sw_client_close (CamSwClient * client)
+{
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (client->state == CAM_SW_CLIENT_STATE_OPEN);
+
+ reset_state (client);
+ client->state = CAM_SW_CLIENT_STATE_CLOSED;
+}
+
+static void
+send_ca_pmt (CamSwClient * client, GObject * pmt,
+ guint8 list_management, guint8 cmd_id)
+{
+ guint8 *buffer;
+ guint buffer_size;
+ guint8 *ca_pmt;
+ guint ca_pmt_size;
+ guint length_field_len;
+ guint header_len;
+
+ ca_pmt = cam_build_ca_pmt (pmt, list_management, cmd_id, &ca_pmt_size);
+
+ length_field_len = cam_calc_length_field_size (ca_pmt_size);
+ header_len = 3 + length_field_len;
+ buffer_size = header_len + ca_pmt_size;
+
+ buffer = g_malloc0 (buffer_size);
+ memcpy (buffer + header_len, ca_pmt, ca_pmt_size);
+
+ /* ca_pmt resource_id */
+ buffer[0] = 0x9F;
+ buffer[1] = 0x80;
+ buffer[2] = 0x32;
+
+ cam_write_length_field (&buffer[3], ca_pmt_size);
+
+ write (client->sock, buffer, buffer_size);
+
+ g_free (ca_pmt);
+ g_free (buffer);
+}
+
+void
+cam_sw_client_set_pmt (CamSwClient * client, GObject * pmt)
+{
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (pmt != NULL);
+
+ return send_ca_pmt (client, pmt, 0x03 /* only */ ,
+ 0x01 /* ok_descrambling */ );
+}
+
+void
+cam_sw_client_update_pmt (CamSwClient * client, GObject * pmt)
+{
+ g_return_if_fail (client != NULL);
+ g_return_if_fail (pmt != NULL);
+
+ return send_ca_pmt (client, pmt, 0x05 /* update */ ,
+ 0x01 /* ok_descrambling */ );
+}