1 /*
2  * camresourcemanager.c - GStreamer CAM (EN50221) Resource Manager
3  * Copyright (C) 2007 Alessandro Decina
4  *
5  * Authors:
6  *   Alessandro Decina <alessandro.d@gmail.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 
24 #include "camresourcemanager.h"
25 
26 #define GST_CAT_DEFAULT cam_debug_cat
27 #define TAG_PROFILE_ENQUIRY 0x9F8010
28 #define TAG_PROFILE_REPLY 0x9F8011
29 #define TAG_PROFILE_CHANGE 0x9F8012
30 
31 static CamReturn session_request_impl (CamALApplication * application,
32     CamSLSession * session, CamSLResourceStatus * status);
33 static CamReturn open_impl (CamALApplication * application,
34     CamSLSession * session);
35 static CamReturn close_impl (CamALApplication * application,
36     CamSLSession * session);
37 static CamReturn data_impl (CamALApplication * application,
38     CamSLSession * session, guint tag, guint8 * buffer, guint length);
39 
40 CamResourceManager *
cam_resource_manager_new(void)41 cam_resource_manager_new (void)
42 {
43   CamALApplication *application;
44   CamResourceManager *mgr;
45 
46   mgr = g_new0 (CamResourceManager, 1);
47   application = CAM_AL_APPLICATION (mgr);
48   _cam_al_application_init (application);
49   application->resource_id = CAM_AL_RESOURCE_MANAGER_ID;
50   application->session_request = session_request_impl;
51   application->open = open_impl;
52   application->close = close_impl;
53   application->data = data_impl;
54 
55   return mgr;
56 }
57 
58 void
cam_resource_manager_destroy(CamResourceManager * mgr)59 cam_resource_manager_destroy (CamResourceManager * mgr)
60 {
61   _cam_al_application_destroy (CAM_AL_APPLICATION (mgr));
62   g_free (mgr);
63 }
64 
65 static CamReturn
session_request_impl(CamALApplication * application,CamSLSession * session,CamSLResourceStatus * status)66 session_request_impl (CamALApplication * application,
67     CamSLSession * session, CamSLResourceStatus * status)
68 {
69   *status = CAM_SL_RESOURCE_STATUS_OPEN;
70 
71   return CAM_RETURN_OK;
72 }
73 
74 static CamReturn
send_simple(CamResourceManager * mgr,CamSLSession * session,guint tag)75 send_simple (CamResourceManager * mgr, CamSLSession * session, guint tag)
76 {
77   guint8 *buffer;
78   guint offset;
79   guint buffer_size;
80   CamReturn ret;
81 
82   cam_al_calc_buffer_size (CAM_AL_APPLICATION (mgr)->al, 0, &buffer_size,
83       &offset);
84   buffer = g_malloc (buffer_size);
85 
86   ret = cam_al_application_write (CAM_AL_APPLICATION (mgr), session,
87       tag, buffer, buffer_size, 0);
88 
89   g_free (buffer);
90 
91   return ret;
92 }
93 
94 static CamReturn
send_profile_enquiry(CamResourceManager * mgr,CamSLSession * session)95 send_profile_enquiry (CamResourceManager * mgr, CamSLSession * session)
96 {
97   GST_DEBUG ("sending profile enquiry");
98   return send_simple (mgr, session, TAG_PROFILE_ENQUIRY);
99 }
100 
101 static CamReturn
send_profile_change(CamResourceManager * mgr,CamSLSession * session)102 send_profile_change (CamResourceManager * mgr, CamSLSession * session)
103 {
104   GST_DEBUG ("sending profile change");
105   return send_simple (mgr, session, TAG_PROFILE_CHANGE);
106 }
107 
108 static CamReturn
send_profile_reply(CamResourceManager * mgr,CamSLSession * session)109 send_profile_reply (CamResourceManager * mgr, CamSLSession * session)
110 {
111   CamReturn ret;
112   guint8 *buffer;
113   guint8 *apdu_body;
114   guint buffer_size;
115   guint offset;
116   GList *resource_ids;
117   guint resource_ids_size;
118   GList *walk;
119 
120   resource_ids = cam_al_get_resource_ids (CAM_AL_APPLICATION (mgr)->al);
121   resource_ids_size = g_list_length (resource_ids) * 4;
122 
123   cam_al_calc_buffer_size (CAM_AL_APPLICATION (mgr)->al, resource_ids_size,
124       &buffer_size, &offset);
125 
126   buffer = g_malloc (buffer_size);
127   apdu_body = buffer + offset;
128 
129   for (walk = resource_ids; walk != NULL; walk = walk->next) {
130     GST_WRITE_UINT32_BE (apdu_body, GPOINTER_TO_UINT (walk->data));
131 
132     apdu_body += 4;
133   }
134 
135   g_list_free (resource_ids);
136 
137   GST_DEBUG ("sending profile reply");
138   ret = cam_al_application_write (CAM_AL_APPLICATION (mgr), session,
139       TAG_PROFILE_REPLY, buffer, buffer_size, resource_ids_size);
140 
141   g_free (buffer);
142 
143   return ret;
144 }
145 
146 static CamReturn
open_impl(CamALApplication * application,CamSLSession * session)147 open_impl (CamALApplication * application, CamSLSession * session)
148 {
149   CamResourceManager *mgr = CAM_RESOURCE_MANAGER (application);
150 
151   return send_profile_enquiry (mgr, session);
152 }
153 
154 static CamReturn
close_impl(CamALApplication * application,CamSLSession * session)155 close_impl (CamALApplication * application, CamSLSession * session)
156 {
157   return CAM_RETURN_OK;
158 }
159 
160 static CamReturn
handle_profile_reply(CamResourceManager * mgr,CamSLSession * session,guint8 * buffer,guint length)161 handle_profile_reply (CamResourceManager * mgr, CamSLSession * session,
162     guint8 * buffer, guint length)
163 {
164   /* the APDU contains length / 4 resource_ids */
165   /* FIXME: implement this once CamApplicationProxy is implemented */
166   GST_DEBUG ("got profile reply");
167   return send_profile_change (mgr, session);
168 }
169 
170 static CamReturn
data_impl(CamALApplication * application,CamSLSession * session,guint tag,guint8 * buffer,guint length)171 data_impl (CamALApplication * application, CamSLSession * session,
172     guint tag, guint8 * buffer, guint length)
173 {
174   CamResourceManager *mgr = CAM_RESOURCE_MANAGER (application);
175 
176   switch (tag) {
177     case TAG_PROFILE_ENQUIRY:
178       send_profile_reply (mgr, session);
179       break;
180     case TAG_PROFILE_REPLY:
181       handle_profile_reply (mgr, session, buffer, length);
182       break;
183     case TAG_PROFILE_CHANGE:
184       send_profile_enquiry (mgr, session);
185       break;
186     default:
187       g_return_val_if_reached (CAM_RETURN_APPLICATION_ERROR);
188   }
189 
190   /* FIXME: Shouldn't this return the retval from the functions above ? */
191   return CAM_RETURN_OK;
192 }
193