1 #include <stdio.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <errno.h>
6 //#include <stdint.h>
7 #include <sys/ioctl.h>
8 #include <sys/mman.h>
9 #include "ionutils.h"
10 #include "ipcsocket.h"
11 
12 
write_buffer(void * buffer,unsigned long len)13 void write_buffer(void *buffer, unsigned long len)
14 {
15 	int i;
16 	unsigned char *ptr = (unsigned char *)buffer;
17 
18 	if (!ptr) {
19 		fprintf(stderr, "<%s>: Invalid buffer...\n", __func__);
20 		return;
21 	}
22 
23 	printf("Fill buffer content:\n");
24 	memset(ptr, 0xfd, len);
25 	for (i = 0; i < len; i++)
26 		printf("0x%x ", ptr[i]);
27 	printf("\n");
28 }
29 
read_buffer(void * buffer,unsigned long len)30 void read_buffer(void *buffer, unsigned long len)
31 {
32 	int i;
33 	unsigned char *ptr = (unsigned char *)buffer;
34 
35 	if (!ptr) {
36 		fprintf(stderr, "<%s>: Invalid buffer...\n", __func__);
37 		return;
38 	}
39 
40 	printf("Read buffer content:\n");
41 	for (i = 0; i < len; i++)
42 		printf("0x%x ", ptr[i]);
43 	printf("\n");
44 }
45 
ion_export_buffer_fd(struct ion_buffer_info * ion_info)46 int ion_export_buffer_fd(struct ion_buffer_info *ion_info)
47 {
48 	int i, ret, ionfd, buffer_fd;
49 	unsigned int heap_id;
50 	unsigned long maplen;
51 	unsigned char *map_buffer;
52 	struct ion_allocation_data alloc_data;
53 	struct ion_heap_query query;
54 	struct ion_heap_data heap_data[MAX_HEAP_COUNT];
55 
56 	if (!ion_info) {
57 		fprintf(stderr, "<%s>: Invalid ion info\n", __func__);
58 		return -1;
59 	}
60 
61 	/* Create an ION client */
62 	ionfd = open(ION_DEVICE, O_RDWR);
63 	if (ionfd < 0) {
64 		fprintf(stderr, "<%s>: Failed to open ion client: %s\n",
65 			__func__, strerror(errno));
66 		return -1;
67 	}
68 
69 	memset(&query, 0, sizeof(query));
70 	query.cnt = MAX_HEAP_COUNT;
71 	query.heaps = (unsigned long int)&heap_data[0];
72 	/* Query ION heap_id_mask from ION heap */
73 	ret = ioctl(ionfd, ION_IOC_HEAP_QUERY, &query);
74 	if (ret < 0) {
75 		fprintf(stderr, "<%s>: Failed: ION_IOC_HEAP_QUERY: %s\n",
76 			__func__, strerror(errno));
77 		goto err_query;
78 	}
79 
80 	heap_id = MAX_HEAP_COUNT + 1;
81 	for (i = 0; i < query.cnt; i++) {
82 		if (heap_data[i].type == ion_info->heap_type) {
83 			heap_id = heap_data[i].heap_id;
84 			break;
85 		}
86 	}
87 
88 	if (heap_id > MAX_HEAP_COUNT) {
89 		fprintf(stderr, "<%s>: ERROR: heap type does not exists\n",
90 			__func__);
91 		goto err_heap;
92 	}
93 
94 	alloc_data.len = ion_info->heap_size;
95 	alloc_data.heap_id_mask = 1 << heap_id;
96 	alloc_data.flags = ion_info->flag_type;
97 
98 	/* Allocate memory for this ION client as per heap_type */
99 	ret = ioctl(ionfd, ION_IOC_ALLOC, &alloc_data);
100 	if (ret < 0) {
101 		fprintf(stderr, "<%s>: Failed: ION_IOC_ALLOC: %s\n",
102 			__func__, strerror(errno));
103 		goto err_alloc;
104 	}
105 
106 	/* This will return a valid buffer fd */
107 	buffer_fd = alloc_data.fd;
108 	maplen = alloc_data.len;
109 
110 	if (buffer_fd < 0 || maplen <= 0) {
111 		fprintf(stderr, "<%s>: Invalid map data, fd: %d, len: %ld\n",
112 			__func__, buffer_fd, maplen);
113 		goto err_fd_data;
114 	}
115 
116 	/* Create memory mapped buffer for the buffer fd */
117 	map_buffer = (unsigned char *)mmap(NULL, maplen, PROT_READ|PROT_WRITE,
118 			MAP_SHARED, buffer_fd, 0);
119 	if (map_buffer == MAP_FAILED) {
120 		fprintf(stderr, "<%s>: Failed: mmap: %s\n",
121 			__func__, strerror(errno));
122 		goto err_mmap;
123 	}
124 
125 	ion_info->ionfd = ionfd;
126 	ion_info->buffd = buffer_fd;
127 	ion_info->buffer = map_buffer;
128 	ion_info->buflen = maplen;
129 
130 	return 0;
131 
132 	munmap(map_buffer, maplen);
133 
134 err_fd_data:
135 err_mmap:
136 	/* in case of error: close the buffer fd */
137 	if (buffer_fd)
138 		close(buffer_fd);
139 
140 err_query:
141 err_heap:
142 err_alloc:
143 	/* In case of error: close the ion client fd */
144 	if (ionfd)
145 		close(ionfd);
146 
147 	return -1;
148 }
149 
ion_import_buffer_fd(struct ion_buffer_info * ion_info)150 int ion_import_buffer_fd(struct ion_buffer_info *ion_info)
151 {
152 	int buffd;
153 	unsigned char *map_buf;
154 	unsigned long map_len;
155 
156 	if (!ion_info) {
157 		fprintf(stderr, "<%s>: Invalid ion info\n", __func__);
158 		return -1;
159 	}
160 
161 	map_len = ion_info->buflen;
162 	buffd = ion_info->buffd;
163 
164 	if (buffd < 0 || map_len <= 0) {
165 		fprintf(stderr, "<%s>: Invalid map data, fd: %d, len: %ld\n",
166 			__func__, buffd, map_len);
167 		goto err_buffd;
168 	}
169 
170 	map_buf = (unsigned char *)mmap(NULL, map_len, PROT_READ|PROT_WRITE,
171 			MAP_SHARED, buffd, 0);
172 	if (map_buf == MAP_FAILED) {
173 		printf("<%s>: Failed - mmap: %s\n",
174 			__func__, strerror(errno));
175 		goto err_mmap;
176 	}
177 
178 	ion_info->buffer = map_buf;
179 	ion_info->buflen = map_len;
180 
181 	return 0;
182 
183 err_mmap:
184 	if (buffd)
185 		close(buffd);
186 
187 err_buffd:
188 	return -1;
189 }
190 
ion_close_buffer_fd(struct ion_buffer_info * ion_info)191 void ion_close_buffer_fd(struct ion_buffer_info *ion_info)
192 {
193 	if (ion_info) {
194 		/* unmap the buffer properly in the end */
195 		munmap(ion_info->buffer, ion_info->buflen);
196 		/* close the buffer fd */
197 		if (ion_info->buffd > 0)
198 			close(ion_info->buffd);
199 		/* Finally, close the client fd */
200 		if (ion_info->ionfd > 0)
201 			close(ion_info->ionfd);
202 	}
203 }
204 
socket_send_fd(struct socket_info * info)205 int socket_send_fd(struct socket_info *info)
206 {
207 	int status;
208 	int fd, sockfd;
209 	struct socketdata skdata;
210 
211 	if (!info) {
212 		fprintf(stderr, "<%s>: Invalid socket info\n", __func__);
213 		return -1;
214 	}
215 
216 	sockfd = info->sockfd;
217 	fd = info->datafd;
218 	memset(&skdata, 0, sizeof(skdata));
219 	skdata.data = fd;
220 	skdata.len = sizeof(skdata.data);
221 	status = sendtosocket(sockfd, &skdata);
222 	if (status < 0) {
223 		fprintf(stderr, "<%s>: Failed: sendtosocket\n", __func__);
224 		return -1;
225 	}
226 
227 	return 0;
228 }
229 
socket_receive_fd(struct socket_info * info)230 int socket_receive_fd(struct socket_info *info)
231 {
232 	int status;
233 	int fd, sockfd;
234 	struct socketdata skdata;
235 
236 	if (!info) {
237 		fprintf(stderr, "<%s>: Invalid socket info\n", __func__);
238 		return -1;
239 	}
240 
241 	sockfd = info->sockfd;
242 	memset(&skdata, 0, sizeof(skdata));
243 	status = receivefromsocket(sockfd, &skdata);
244 	if (status < 0) {
245 		fprintf(stderr, "<%s>: Failed: receivefromsocket\n", __func__);
246 		return -1;
247 	}
248 
249 	fd = (int)skdata.data;
250 	info->datafd = fd;
251 
252 	return status;
253 }
254