1 /**************************************************************************
5 Copyright 2012 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: SooChan Lim <sc1.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>
8 Boram Park <boram1288.park@samsung.com>, Changyeon Lee <cyeon.lee@samsung.com>
10 Permission is hereby granted, free of charge, to any person obtaining a
11 copy of this software and associated documentation files (the
12 "Software"), to deal in the Software without restriction, including
13 without limitation the rights to use, copy, modify, merge, publish,
14 distribute, sub license, and/or sell copies of the Software, and to
15 permit persons to whom the Software is furnished to do so, subject to
16 the following conditions:
18 The above copyright notice and this permission notice (including the
19 next paragraph) shall be included in all copies or substantial portions
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 **************************************************************************/
32 #define WL_HIDE_DEPRECATED
39 #include "tbm_bufmgr_int.h"
41 #include "wayland-tbm-drm-auth-server-protocol.h"
43 struct wayland_tbm_drm_auth_server {
44 struct wl_display *display;
45 struct wl_global *wl_tbm_drm_auth_global;
52 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
54 struct wayland_tbm_drm_auth_server *tbm_drm_auth_srv;
58 _send_server_auth_info(struct wayland_tbm_drm_auth_server *tbm_drm_auth_srv,
59 struct wl_resource *resource)
62 uint32_t capabilities;
63 char *device_name = NULL;
64 drm_magic_t magic = 0;
66 fd = open(tbm_drm_auth_srv->device_name, O_RDWR | O_CLOEXEC);
67 if (fd == -1 && errno == EINVAL) {
68 fd = open(tbm_drm_auth_srv->device_name, O_RDWR);
70 fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
74 TBM_LOG_E("failed to open drm : device_name, %s\n", tbm_drm_auth_srv->device_name);
76 wl_resource_post_error(resource, WL_TBM_DRM_AUTH_ERROR_AUTHENTICATE_FAIL,
77 "authenicate failed::open_drm");
81 if (drmGetMagic(fd, &magic) < 0) {
82 if (errno != EACCES) {
83 TBM_LOG_E("failed to get magic\n");
85 wl_resource_post_error(resource, WL_TBM_DRM_AUTH_ERROR_AUTHENTICATE_FAIL,
86 "authenicate failed::get_magic");
91 if (drmAuthMagic(tbm_drm_auth_srv->fd, magic) < 0) {
92 TBM_LOG_E("failed to authenticate magic\n");
94 wl_resource_post_error(resource, WL_TBM_DRM_AUTH_ERROR_AUTHENTICATE_FAIL,
95 "authenicate failed::auth_magic");
99 capabilities = tbm_drm_auth_srv->flags;
100 device_name = tbm_drm_auth_srv->device_name;
103 wl_tbm_drm_auth_send_authentication_info(resource, device_name, capabilities, fd);
109 if (device_name && device_name != tbm_drm_auth_srv->device_name)
115 _wayland_tbm_drm_auth_server_impl_get_authentication_info(struct wl_client *client,
116 struct wl_resource *resource)
118 struct wayland_tbm_drm_auth_server *tbm_drm_auth_srv = wl_resource_get_user_data(resource);
120 /* if display server is the client of the host display server, for embedded server */
121 _send_server_auth_info(tbm_drm_auth_srv, resource);
125 static const struct wl_tbm_drm_auth_interface _wayland_tbm_drm_auth_server_implementation = {
126 _wayland_tbm_drm_auth_server_impl_get_authentication_info,
130 _wayland_tbm_drm_auth_server_bind_cb(struct wl_client *client, void *data,
134 struct wl_resource *resource;
136 resource = wl_resource_create(client, &wl_tbm_drm_auth_interface, MIN(version, 1), id);
138 wl_client_post_no_memory(client);
142 wl_resource_set_implementation(resource,
143 &_wayland_tbm_drm_auth_server_implementation,
149 _tbm_getgrnam_r(const char *name)
151 struct group *grp = NULL;
152 struct group *grp_res = NULL;
158 buf_len = sysconf(_SC_GETGR_R_SIZE_MAX);
162 buf = calloc(1, buf_len * sizeof(char));
164 TBM_LOG_E("creating buffer failed\n");
168 grp = calloc(1, sizeof(struct group));
170 TBM_LOG_E("creating group failed\n");
174 ret = getgrnam_r(name, grp, buf, buf_len, &grp_res);
176 TBM_LOG_E("getgrnam_r failed errno:%d(%m)\n", ret);
180 if (grp_res == NULL) {
181 TBM_LOG_E("finding name:%s group failed\n", name);
201 _tbm_drm_auth_socket_init(struct wayland_tbm_drm_auth_server *tbm_drm_auth_srv)
203 const char *dir = NULL;
204 char socket_path[128];
209 if (wl_display_add_socket(tbm_drm_auth_srv->display, "tbm-drm-auth")) {
210 TBM_LOG_E("createing a tdm-socket failed\n");
214 dir = getenv("XDG_RUNTIME_DIR");
216 TBM_LOG_E("getting XDG_RUNTIME_DIR failed\n");
220 snprintf(socket_path, sizeof(socket_path), "%s/%s", dir, "tbm-drm-auth");
222 ret = chmod(socket_path, 509);
224 TBM_LOG_E("changing modes of socket file failed:%s (%m)\n", socket_path);
228 /* if not super user, we don't need to change owner and group */
232 ret = _tbm_getgrnam_r("root");
234 TBM_LOG_E("getting uid failed\n");
239 ret = _tbm_getgrnam_r("display");
241 TBM_LOG_E("getting gid failed\n");
246 ret = chown(socket_path, uid, gid);
248 TBM_LOG_E("changing owner of socket file failed:%s (%m)\n", socket_path);
256 tbm_drm_helper_wl_auth_server_init(void *wl_display, int fd, const char *device_name, uint32_t flags)
258 if (!tbm_drm_auth_srv) {
259 TBM_RETURN_VAL_IF_FAIL(wl_display != NULL, 0);
261 tbm_drm_auth_srv = calloc(1, sizeof(struct wayland_tbm_drm_auth_server));
262 TBM_RETURN_VAL_IF_FAIL(tbm_drm_auth_srv != NULL, 0);
264 tbm_drm_auth_srv->display = (struct wl_display *)wl_display;
265 tbm_drm_auth_srv->device_name = strdup(device_name);
266 tbm_drm_auth_srv->fd = fd;
267 tbm_drm_auth_srv->flags = flags;
269 if (!_tbm_drm_auth_socket_init(tbm_drm_auth_srv)) {
270 TBM_LOG_E("[TBM_DRM] fail to _tbm_drm_auth_socket_init\n");
272 if (tbm_drm_auth_srv->device_name)
273 free(tbm_drm_auth_srv->device_name);
275 free(tbm_drm_auth_srv);
276 tbm_drm_auth_srv = NULL;
281 /* init the client resource list */
282 tbm_drm_auth_srv->wl_tbm_drm_auth_global = wl_global_create(tbm_drm_auth_srv->display, &wl_tbm_drm_auth_interface, 1,
283 tbm_drm_auth_srv, _wayland_tbm_drm_auth_server_bind_cb);
290 tbm_drm_helper_wl_auth_server_deinit(void)
292 if (tbm_drm_auth_srv) {
293 wl_global_destroy(tbm_drm_auth_srv->wl_tbm_drm_auth_global);
295 if (tbm_drm_auth_srv->device_name)
296 free(tbm_drm_auth_srv->device_name);
298 free(tbm_drm_auth_srv);
299 tbm_drm_auth_srv = NULL;
304 tbm_drm_helper_get_master_fd(void)
312 value = (const char*)getenv("TDM_DRM_MASTER_FD");
316 const long sl = strtol(value, &end, 10);
318 TBM_LOG_E("%s: not a decimal number\n", value);
320 } else if (*end != '\0') {
321 TBM_LOG_E("%s: extra characters at end of input: %s\n", value, end);
323 } else if ((sl == LONG_MIN || sl == LONG_MAX) && errno == ERANGE) {
324 TBM_LOG_E("%s out of range of type long\n", value);
326 } else if (sl > INT_MAX) {
327 TBM_LOG_E("%ld greater than INT_MAX\n", sl);
329 } else if (sl < INT_MIN) {
330 TBM_LOG_E("%ld less than INT_MIN\n", sl);
335 TBM_LOG_E("%d out of fd range\n", fd);
340 TBM_LOG_I("TDM_DRM_MASTER_FD: %d\n", fd);
342 flags = fcntl(fd, F_GETFD);
344 TBM_LOG_E("fcntl failed: %m");
350 TBM_LOG_E("dup failed: %m");
354 fcntl(new_fd, F_SETFD, flags|FD_CLOEXEC);
356 TBM_LOG_I("Return MASTER_FD: %d\n", new_fd);
362 tbm_drm_helper_set_tbm_master_fd(int fd)
367 snprintf(buf, sizeof(buf), "%d", fd);
369 ret = setenv("TBM_DRM_MASTER_FD", (const char*)buf, 1);
371 TBM_LOG_E("failed to set TIZEN_DRM_MASTER_FD to %d\n", fd);
375 TBM_LOG_I("TBM_DRM_MASTER_FD: %d\n", fd);
379 tbm_drm_helper_unset_tbm_master_fd(void)
383 ret = unsetenv("TBM_DRM_MASTER_FD");
385 TBM_LOG_E("failed to unset TBM_DRM_MASTER_FD\n");