1 /* 2 * Provide a server offering a compound interface. 3 * 4 * Copyright (C) 2020 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include <l4/re/env.h> 23 #include <l4/sys/err.h> 24 25 #include <math.h> 26 #include <stdio.h> 27 28 #include <ipc/server.h> 29 30 #include "calc_counter_server.h" 31 32 33 34 /* Component methods. */ 35 36 static long calc_add(ref_Calc _self, int left, int right, int *result) 37 { 38 (void) _self; 39 *result = left + right; 40 return L4_EOK; 41 } 42 43 static long calc_subtract(ref_Calc _self, int left, int right, int *result) 44 { 45 (void) _self; 46 *result = left - right; 47 return L4_EOK; 48 } 49 50 static long calc_multiply(ref_Calc _self, int left, int right, int *result) 51 { 52 (void) _self; 53 *result = left * right; 54 return L4_EOK; 55 } 56 57 static long calc_divide(ref_Calc _self, int numerator, int denominator, int *result) 58 { 59 (void) _self; 60 *result = numerator / denominator; 61 return L4_EOK; 62 } 63 64 static long calc_pow(ref_Calc _self, double base, double exponent, double *result) 65 { 66 (void) _self; 67 *result = powf(base, exponent); 68 return L4_EOK; 69 } 70 71 72 73 /* Component state and methods. */ 74 75 static int counter = 0; 76 77 static long counter_increment(ref_Counter _self, int *result) 78 { 79 int *counter = (int *) (_self.ptr); 80 81 *counter = *counter + 1; 82 *result = *counter; 83 return L4_EOK; 84 } 85 86 87 88 /* Interfaces for this component. */ 89 90 iface_Calc server_iface_Calc = { 91 .add=calc_add, 92 .subtract=calc_subtract, 93 .multiply=calc_multiply, 94 .divide=calc_divide, 95 .pow=calc_pow 96 }; 97 98 iface_Counter server_iface_Counter = { 99 .increment=counter_increment 100 }; 101 102 /* The compound interface referencing the individual interfaces. */ 103 104 iface_CalcCounter server_iface_CalcCounter = { 105 .to_Calc=&server_iface_Calc, 106 .to_Counter=&server_iface_Counter 107 }; 108 109 110 111 int main(void) 112 { 113 /* Reference to state information and an encapsulation. */ 114 115 ref_CalcCounter ref = {.ptr=&counter}; 116 CalcCounter obj = {.ref=ref, .iface=&server_iface_CalcCounter}; 117 118 /* Server capability. */ 119 120 l4_cap_idx_t server; 121 122 /* Register a server associating it with the given object. */ 123 124 long err = ipc_server_bind("server", (l4_umword_t) &obj, &server); 125 126 if (err) 127 { 128 printf("Could not bind server: %s\n", l4sys_errtostr(err)); 129 return 1; 130 } 131 132 /* Wait for messages, dispatching to the handler. */ 133 134 ipc_server_loop(CalcCounter_expected_items, &obj, 135 (ipc_server_handler_type) handle_CalcCounter); 136 137 return 0; 138 }