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 13void 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 30void 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 46int 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 134err_fd_data: 135err_mmap: 136 /* in case of error: close the buffer fd */ 137 if (buffer_fd) 138 close(buffer_fd); 139 140err_query: 141err_heap: 142err_alloc: 143 /* In case of error: close the ion client fd */ 144 if (ionfd) 145 close(ionfd); 146 147 return -1; 148} 149 150int 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 183err_mmap: 184 if (buffd) 185 close(buffd); 186 187err_buffd: 188 return -1; 189} 190 191void 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 205int 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 230int 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