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