1 /*
2  *  tvheadend - API access to Conditional Access Clients
3  *
4  *  Copyright (C) 2014 Jaroslav Kysela
5  *
6  *  This program is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #include "tvheadend.h"
21 #include "access.h"
22 #include "htsmsg.h"
23 #include "api.h"
24 #include "descrambler/caclient.h"
25 
26 /*
27  *
28  */
29 static int
api_caclient_list(access_t * perm,void * opaque,const char * op,htsmsg_t * args,htsmsg_t ** resp)30 api_caclient_list
31   ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
32 {
33   caclient_t *cac;
34   htsmsg_t *l, *e;
35   char ubuf[UUID_HEX_SIZE];
36 
37   l = htsmsg_create_list();
38   pthread_mutex_lock(&global_lock);
39   TAILQ_FOREACH(cac, &caclients, cac_link) {
40     e = htsmsg_create_map();
41     htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&cac->cac_id, ubuf));
42     htsmsg_add_str(e, "title", idnode_get_title(&cac->cac_id, perm->aa_lang_ui));
43     htsmsg_add_str(e, "status", caclient_get_status(cac));
44     htsmsg_add_msg(l, NULL, e);
45   }
46   pthread_mutex_unlock(&global_lock);
47   *resp = htsmsg_create_map();
48   htsmsg_add_msg(*resp, "entries", l);
49   return 0;
50 }
51 
52 static int
api_caclient_builders(access_t * perm,void * opaque,const char * op,htsmsg_t * args,htsmsg_t ** resp)53 api_caclient_builders
54   ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
55 {
56   const idclass_t **r;
57   htsmsg_t *l, *e;
58 
59   /* List of available builder classes */
60   l = htsmsg_create_list();
61   for (r = caclient_classes; *r; r++)
62     if ((e = idclass_serialize(*r, perm->aa_lang_ui)))
63       htsmsg_add_msg(l, NULL, e);
64 
65   /* Output */
66   *resp = htsmsg_create_map();
67   htsmsg_add_msg(*resp, "entries", l);
68 
69   return 0;
70 }
71 
72 static int
api_caclient_create(access_t * perm,void * opaque,const char * op,htsmsg_t * args,htsmsg_t ** resp)73 api_caclient_create
74   ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
75 {
76   int err = 0;
77   const char *clazz;
78   htsmsg_t *conf;
79   caclient_t *cac;
80 
81   if (!(clazz = htsmsg_get_str(args, "class")))
82     return EINVAL;
83   if (!(conf  = htsmsg_get_map(args, "conf")))
84     return EINVAL;
85   htsmsg_set_str(conf, "class", clazz);
86 
87   pthread_mutex_lock(&global_lock);
88   cac = caclient_create(NULL, conf, 1);
89   if (cac)
90     api_idnode_create(resp, &cac->cac_id);
91   else
92     err = -EINVAL;
93   pthread_mutex_unlock(&global_lock);
94 
95   return err;
96 }
97 
98 /*
99  * Init
100  */
101 void
api_caclient_init(void)102 api_caclient_init ( void )
103 {
104   static api_hook_t ah[] = {
105     { "caclient/list",       ACCESS_ADMIN, api_caclient_list,     NULL },
106     { "caclient/class",      ACCESS_ADMIN, api_idnode_class, (void*)&caclient_class },
107     { "caclient/builders",   ACCESS_ADMIN, api_caclient_builders, NULL },
108     { "caclient/create",     ACCESS_ADMIN, api_caclient_create,   NULL },
109     { NULL },
110   };
111 
112   api_register_all(ah);
113 }
114