1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * ionapp_export.c
4  *
5  * It is a user space utility to create and export android
6  * ion memory buffer fd to another process using unix domain socket as IPC.
7  * This acts like a server for ionapp_import(client).
8  * So, this server has to be started first before the client.
9  *
10  * Copyright (C) 2017 Pintu Kumar <pintu.ping@gmail.com>
11  */
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <unistd.h>
17 #include <errno.h>
18 #include <sys/time.h>
19 #include "ionutils.h"
20 #include "ipcsocket.h"
21 
22 
print_usage(int argc,char * argv[])23 void print_usage(int argc, char *argv[])
24 {
25 	printf("Usage: %s [-h <help>] [-i <heap id>] [-s <size in bytes>]\n",
26 		argv[0]);
27 }
28 
main(int argc,char * argv[])29 int main(int argc, char *argv[])
30 {
31 	int opt, ret, status, heapid;
32 	int sockfd, client_fd, shared_fd;
33 	unsigned char *map_buf;
34 	unsigned long map_len, heap_type, heap_size, flags;
35 	struct ion_buffer_info info;
36 	struct socket_info skinfo;
37 
38 	if (argc < 2) {
39 		print_usage(argc, argv);
40 		return -1;
41 	}
42 
43 	heap_size = 0;
44 	flags = 0;
45 	heap_type = ION_HEAP_TYPE_SYSTEM;
46 
47 	while ((opt = getopt(argc, argv, "hi:s:")) != -1) {
48 		switch (opt) {
49 		case 'h':
50 			print_usage(argc, argv);
51 			exit(0);
52 			break;
53 		case 'i':
54 			heapid = atoi(optarg);
55 			switch (heapid) {
56 			case 0:
57 				heap_type = ION_HEAP_TYPE_SYSTEM;
58 				break;
59 			case 1:
60 				heap_type = ION_HEAP_TYPE_SYSTEM_CONTIG;
61 				break;
62 			default:
63 				printf("ERROR: heap type not supported\n");
64 				exit(1);
65 			}
66 			break;
67 		case 's':
68 			heap_size = atoi(optarg);
69 			break;
70 		default:
71 			print_usage(argc, argv);
72 			exit(1);
73 			break;
74 		}
75 	}
76 
77 	if (heap_size <= 0) {
78 		printf("heap_size cannot be 0\n");
79 		print_usage(argc, argv);
80 		exit(1);
81 	}
82 
83 	printf("heap_type: %ld, heap_size: %ld\n", heap_type, heap_size);
84 	info.heap_type = heap_type;
85 	info.heap_size = heap_size;
86 	info.flag_type = flags;
87 
88 	/* This is server: open the socket connection first */
89 	/* Here; 1 indicates server or exporter */
90 	status = opensocket(&sockfd, SOCKET_NAME, 1);
91 	if (status < 0) {
92 		fprintf(stderr, "<%s>: Failed opensocket.\n", __func__);
93 		goto err_socket;
94 	}
95 	skinfo.sockfd = sockfd;
96 
97 	ret = ion_export_buffer_fd(&info);
98 	if (ret < 0) {
99 		fprintf(stderr, "FAILED: ion_get_buffer_fd\n");
100 		goto err_export;
101 	}
102 	client_fd = info.ionfd;
103 	shared_fd = info.buffd;
104 	map_buf = info.buffer;
105 	map_len = info.buflen;
106 	write_buffer(map_buf, map_len);
107 
108 	/* share ion buf fd with other user process */
109 	printf("Sharing fd: %d, Client fd: %d\n", shared_fd, client_fd);
110 	skinfo.datafd = shared_fd;
111 	skinfo.buflen = map_len;
112 
113 	ret = socket_send_fd(&skinfo);
114 	if (ret < 0) {
115 		fprintf(stderr, "FAILED: socket_send_fd\n");
116 		goto err_send;
117 	}
118 
119 err_send:
120 err_export:
121 	ion_close_buffer_fd(&info);
122 
123 err_socket:
124 	closesocket(sockfd, SOCKET_NAME);
125 
126 	return 0;
127 }
128