18c2ecf20Sopenharmony_ci#include <stdio.h> 28c2ecf20Sopenharmony_ci#include <string.h> 38c2ecf20Sopenharmony_ci#include <unistd.h> 48c2ecf20Sopenharmony_ci#include <fcntl.h> 58c2ecf20Sopenharmony_ci#include <errno.h> 68c2ecf20Sopenharmony_ci//#include <stdint.h> 78c2ecf20Sopenharmony_ci#include <sys/ioctl.h> 88c2ecf20Sopenharmony_ci#include <sys/mman.h> 98c2ecf20Sopenharmony_ci#include "ionutils.h" 108c2ecf20Sopenharmony_ci#include "ipcsocket.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_civoid write_buffer(void *buffer, unsigned long len) 148c2ecf20Sopenharmony_ci{ 158c2ecf20Sopenharmony_ci int i; 168c2ecf20Sopenharmony_ci unsigned char *ptr = (unsigned char *)buffer; 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci if (!ptr) { 198c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Invalid buffer...\n", __func__); 208c2ecf20Sopenharmony_ci return; 218c2ecf20Sopenharmony_ci } 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci printf("Fill buffer content:\n"); 248c2ecf20Sopenharmony_ci memset(ptr, 0xfd, len); 258c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) 268c2ecf20Sopenharmony_ci printf("0x%x ", ptr[i]); 278c2ecf20Sopenharmony_ci printf("\n"); 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_civoid read_buffer(void *buffer, unsigned long len) 318c2ecf20Sopenharmony_ci{ 328c2ecf20Sopenharmony_ci int i; 338c2ecf20Sopenharmony_ci unsigned char *ptr = (unsigned char *)buffer; 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci if (!ptr) { 368c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Invalid buffer...\n", __func__); 378c2ecf20Sopenharmony_ci return; 388c2ecf20Sopenharmony_ci } 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci printf("Read buffer content:\n"); 418c2ecf20Sopenharmony_ci for (i = 0; i < len; i++) 428c2ecf20Sopenharmony_ci printf("0x%x ", ptr[i]); 438c2ecf20Sopenharmony_ci printf("\n"); 448c2ecf20Sopenharmony_ci} 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ciint ion_export_buffer_fd(struct ion_buffer_info *ion_info) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci int i, ret, ionfd, buffer_fd; 498c2ecf20Sopenharmony_ci unsigned int heap_id; 508c2ecf20Sopenharmony_ci unsigned long maplen; 518c2ecf20Sopenharmony_ci unsigned char *map_buffer; 528c2ecf20Sopenharmony_ci struct ion_allocation_data alloc_data; 538c2ecf20Sopenharmony_ci struct ion_heap_query query; 548c2ecf20Sopenharmony_ci struct ion_heap_data heap_data[MAX_HEAP_COUNT]; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci if (!ion_info) { 578c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Invalid ion info\n", __func__); 588c2ecf20Sopenharmony_ci return -1; 598c2ecf20Sopenharmony_ci } 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci /* Create an ION client */ 628c2ecf20Sopenharmony_ci ionfd = open(ION_DEVICE, O_RDWR); 638c2ecf20Sopenharmony_ci if (ionfd < 0) { 648c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Failed to open ion client: %s\n", 658c2ecf20Sopenharmony_ci __func__, strerror(errno)); 668c2ecf20Sopenharmony_ci return -1; 678c2ecf20Sopenharmony_ci } 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci memset(&query, 0, sizeof(query)); 708c2ecf20Sopenharmony_ci query.cnt = MAX_HEAP_COUNT; 718c2ecf20Sopenharmony_ci query.heaps = (unsigned long int)&heap_data[0]; 728c2ecf20Sopenharmony_ci /* Query ION heap_id_mask from ION heap */ 738c2ecf20Sopenharmony_ci ret = ioctl(ionfd, ION_IOC_HEAP_QUERY, &query); 748c2ecf20Sopenharmony_ci if (ret < 0) { 758c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Failed: ION_IOC_HEAP_QUERY: %s\n", 768c2ecf20Sopenharmony_ci __func__, strerror(errno)); 778c2ecf20Sopenharmony_ci goto err_query; 788c2ecf20Sopenharmony_ci } 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci heap_id = MAX_HEAP_COUNT + 1; 818c2ecf20Sopenharmony_ci for (i = 0; i < query.cnt; i++) { 828c2ecf20Sopenharmony_ci if (heap_data[i].type == ion_info->heap_type) { 838c2ecf20Sopenharmony_ci heap_id = heap_data[i].heap_id; 848c2ecf20Sopenharmony_ci break; 858c2ecf20Sopenharmony_ci } 868c2ecf20Sopenharmony_ci } 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci if (heap_id > MAX_HEAP_COUNT) { 898c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: ERROR: heap type does not exists\n", 908c2ecf20Sopenharmony_ci __func__); 918c2ecf20Sopenharmony_ci goto err_heap; 928c2ecf20Sopenharmony_ci } 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci alloc_data.len = ion_info->heap_size; 958c2ecf20Sopenharmony_ci alloc_data.heap_id_mask = 1 << heap_id; 968c2ecf20Sopenharmony_ci alloc_data.flags = ion_info->flag_type; 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_ci /* Allocate memory for this ION client as per heap_type */ 998c2ecf20Sopenharmony_ci ret = ioctl(ionfd, ION_IOC_ALLOC, &alloc_data); 1008c2ecf20Sopenharmony_ci if (ret < 0) { 1018c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Failed: ION_IOC_ALLOC: %s\n", 1028c2ecf20Sopenharmony_ci __func__, strerror(errno)); 1038c2ecf20Sopenharmony_ci goto err_alloc; 1048c2ecf20Sopenharmony_ci } 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci /* This will return a valid buffer fd */ 1078c2ecf20Sopenharmony_ci buffer_fd = alloc_data.fd; 1088c2ecf20Sopenharmony_ci maplen = alloc_data.len; 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci if (buffer_fd < 0 || maplen <= 0) { 1118c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Invalid map data, fd: %d, len: %ld\n", 1128c2ecf20Sopenharmony_ci __func__, buffer_fd, maplen); 1138c2ecf20Sopenharmony_ci goto err_fd_data; 1148c2ecf20Sopenharmony_ci } 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci /* Create memory mapped buffer for the buffer fd */ 1178c2ecf20Sopenharmony_ci map_buffer = (unsigned char *)mmap(NULL, maplen, PROT_READ|PROT_WRITE, 1188c2ecf20Sopenharmony_ci MAP_SHARED, buffer_fd, 0); 1198c2ecf20Sopenharmony_ci if (map_buffer == MAP_FAILED) { 1208c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Failed: mmap: %s\n", 1218c2ecf20Sopenharmony_ci __func__, strerror(errno)); 1228c2ecf20Sopenharmony_ci goto err_mmap; 1238c2ecf20Sopenharmony_ci } 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci ion_info->ionfd = ionfd; 1268c2ecf20Sopenharmony_ci ion_info->buffd = buffer_fd; 1278c2ecf20Sopenharmony_ci ion_info->buffer = map_buffer; 1288c2ecf20Sopenharmony_ci ion_info->buflen = maplen; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci return 0; 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci munmap(map_buffer, maplen); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cierr_fd_data: 1358c2ecf20Sopenharmony_cierr_mmap: 1368c2ecf20Sopenharmony_ci /* in case of error: close the buffer fd */ 1378c2ecf20Sopenharmony_ci if (buffer_fd) 1388c2ecf20Sopenharmony_ci close(buffer_fd); 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cierr_query: 1418c2ecf20Sopenharmony_cierr_heap: 1428c2ecf20Sopenharmony_cierr_alloc: 1438c2ecf20Sopenharmony_ci /* In case of error: close the ion client fd */ 1448c2ecf20Sopenharmony_ci if (ionfd) 1458c2ecf20Sopenharmony_ci close(ionfd); 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci return -1; 1488c2ecf20Sopenharmony_ci} 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ciint ion_import_buffer_fd(struct ion_buffer_info *ion_info) 1518c2ecf20Sopenharmony_ci{ 1528c2ecf20Sopenharmony_ci int buffd; 1538c2ecf20Sopenharmony_ci unsigned char *map_buf; 1548c2ecf20Sopenharmony_ci unsigned long map_len; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci if (!ion_info) { 1578c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Invalid ion info\n", __func__); 1588c2ecf20Sopenharmony_ci return -1; 1598c2ecf20Sopenharmony_ci } 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci map_len = ion_info->buflen; 1628c2ecf20Sopenharmony_ci buffd = ion_info->buffd; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci if (buffd < 0 || map_len <= 0) { 1658c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Invalid map data, fd: %d, len: %ld\n", 1668c2ecf20Sopenharmony_ci __func__, buffd, map_len); 1678c2ecf20Sopenharmony_ci goto err_buffd; 1688c2ecf20Sopenharmony_ci } 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci map_buf = (unsigned char *)mmap(NULL, map_len, PROT_READ|PROT_WRITE, 1718c2ecf20Sopenharmony_ci MAP_SHARED, buffd, 0); 1728c2ecf20Sopenharmony_ci if (map_buf == MAP_FAILED) { 1738c2ecf20Sopenharmony_ci printf("<%s>: Failed - mmap: %s\n", 1748c2ecf20Sopenharmony_ci __func__, strerror(errno)); 1758c2ecf20Sopenharmony_ci goto err_mmap; 1768c2ecf20Sopenharmony_ci } 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci ion_info->buffer = map_buf; 1798c2ecf20Sopenharmony_ci ion_info->buflen = map_len; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci return 0; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_cierr_mmap: 1848c2ecf20Sopenharmony_ci if (buffd) 1858c2ecf20Sopenharmony_ci close(buffd); 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_cierr_buffd: 1888c2ecf20Sopenharmony_ci return -1; 1898c2ecf20Sopenharmony_ci} 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_civoid ion_close_buffer_fd(struct ion_buffer_info *ion_info) 1928c2ecf20Sopenharmony_ci{ 1938c2ecf20Sopenharmony_ci if (ion_info) { 1948c2ecf20Sopenharmony_ci /* unmap the buffer properly in the end */ 1958c2ecf20Sopenharmony_ci munmap(ion_info->buffer, ion_info->buflen); 1968c2ecf20Sopenharmony_ci /* close the buffer fd */ 1978c2ecf20Sopenharmony_ci if (ion_info->buffd > 0) 1988c2ecf20Sopenharmony_ci close(ion_info->buffd); 1998c2ecf20Sopenharmony_ci /* Finally, close the client fd */ 2008c2ecf20Sopenharmony_ci if (ion_info->ionfd > 0) 2018c2ecf20Sopenharmony_ci close(ion_info->ionfd); 2028c2ecf20Sopenharmony_ci } 2038c2ecf20Sopenharmony_ci} 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ciint socket_send_fd(struct socket_info *info) 2068c2ecf20Sopenharmony_ci{ 2078c2ecf20Sopenharmony_ci int status; 2088c2ecf20Sopenharmony_ci int fd, sockfd; 2098c2ecf20Sopenharmony_ci struct socketdata skdata; 2108c2ecf20Sopenharmony_ci 2118c2ecf20Sopenharmony_ci if (!info) { 2128c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Invalid socket info\n", __func__); 2138c2ecf20Sopenharmony_ci return -1; 2148c2ecf20Sopenharmony_ci } 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci sockfd = info->sockfd; 2178c2ecf20Sopenharmony_ci fd = info->datafd; 2188c2ecf20Sopenharmony_ci memset(&skdata, 0, sizeof(skdata)); 2198c2ecf20Sopenharmony_ci skdata.data = fd; 2208c2ecf20Sopenharmony_ci skdata.len = sizeof(skdata.data); 2218c2ecf20Sopenharmony_ci status = sendtosocket(sockfd, &skdata); 2228c2ecf20Sopenharmony_ci if (status < 0) { 2238c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Failed: sendtosocket\n", __func__); 2248c2ecf20Sopenharmony_ci return -1; 2258c2ecf20Sopenharmony_ci } 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci return 0; 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ciint socket_receive_fd(struct socket_info *info) 2318c2ecf20Sopenharmony_ci{ 2328c2ecf20Sopenharmony_ci int status; 2338c2ecf20Sopenharmony_ci int fd, sockfd; 2348c2ecf20Sopenharmony_ci struct socketdata skdata; 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_ci if (!info) { 2378c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Invalid socket info\n", __func__); 2388c2ecf20Sopenharmony_ci return -1; 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci sockfd = info->sockfd; 2428c2ecf20Sopenharmony_ci memset(&skdata, 0, sizeof(skdata)); 2438c2ecf20Sopenharmony_ci status = receivefromsocket(sockfd, &skdata); 2448c2ecf20Sopenharmony_ci if (status < 0) { 2458c2ecf20Sopenharmony_ci fprintf(stderr, "<%s>: Failed: receivefromsocket\n", __func__); 2468c2ecf20Sopenharmony_ci return -1; 2478c2ecf20Sopenharmony_ci } 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci fd = (int)skdata.data; 2508c2ecf20Sopenharmony_ci info->datafd = fd; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci return status; 2538c2ecf20Sopenharmony_ci} 254