00001
00002
00003
00004
00005
00006
00007
00008 #include "local.h"
00009 #include <stdlib.h>
00010
00011 #include <l4/names/libnames.h>
00012
00013 ore_client_conn_desc descriptor_table[CONN_MAX];
00014 int ore_initialized = 0;
00015
00016 static int get_free_descriptor(void);
00017 static void release_descriptor(int idx);
00018 static int ore_initialize(void);
00019
00020 #define ORE_NUM_LOOKUPS 10
00021
00022
00023 static int get_free_descriptor(void)
00024 {
00025 int i=0;
00026 do
00027 {
00028 if (l4_is_invalid_id(descriptor_table[i].remote_worker_thread))
00029 return i;
00030 }
00031 while (++i < CONN_MAX);
00032
00033 return -1;
00034 }
00035
00036
00037 static void release_descriptor(int idx)
00038 {
00039 descriptor_table[idx].remote_worker_thread = L4_INVALID_ID;
00040 }
00041
00042
00043 static int ore_initialize(void)
00044 {
00045 int i=0;
00046
00047
00048 for (i=0; i<CONN_MAX; i++)
00049 {
00050 release_descriptor(i);
00051 }
00052
00053 #ifdef ORE_DSI
00054 i = dsi_init();
00055 LOG("dsi_init: %d", i);
00056 #endif
00057
00058 ore_initialized = 1;
00059 return 0;
00060 }
00061
00062 int l4ore_recv_blocking(int handle, char **buf, l4_size_t *size, l4_timeout_t timeout)
00063 {
00064 l4ore_handle_t channel = descriptor_table[handle].remote_worker_thread;
00065 return descriptor_table[handle].rx_func_blocking(channel, handle, buf, size, timeout);
00066 }
00067
00068 int l4ore_recv_nonblocking(int handle, char **buf, l4_size_t *size)
00069 {
00070 l4ore_handle_t channel = descriptor_table[handle].remote_worker_thread;
00071 return descriptor_table[handle].rx_func_nonblocking(channel, handle, buf, size);
00072 }
00073
00074 int l4ore_send(int handle, char *buf, l4_size_t size)
00075 {
00076 l4ore_handle_t channel = descriptor_table[handle].remote_worker_thread;
00077 return descriptor_table[handle].send_func(channel, handle, buf, size);
00078 }
00079
00080 int l4ore_open(char *device, unsigned char mac[6], l4ore_config *conf)
00081 {
00082
00083 l4ore_handle_t ret;
00084 int desc, err = 0;
00085 #ifdef ORE_DSI
00086 dsi_socket_t *send = NULL;
00087 dsi_socket_t *receive = NULL;
00088 #endif
00089
00090 LOG_Enter();
00091
00092 if (!conf)
00093 {
00094 LOG_Error("invalid connection configuration");
00095 return -L4_EINVAL;
00096 }
00097
00098
00099 if (!ore_initialized)
00100 err = ore_initialize();
00101 if (err)
00102 return -L4_EINVAL;
00103
00104 desc = get_free_descriptor();
00105 LOG("descriptor: %d", desc);
00106
00107
00108 if (desc < 0)
00109 {
00110 LOG_Error("out of descriptor memory");
00111 return -L4_ENOMEM;
00112 }
00113
00114
00115 if (strlen(conf->ro_orename) == 0)
00116 strncpy(conf->ro_orename, "ORe", sizeof(conf->ro_orename)-1);
00117 if (ore_lookup_server(conf->ro_orename, &descriptor_table[desc].remote_manager_thread))
00118 {
00119 release_descriptor(desc);
00120 return -1;
00121 }
00122
00123 #ifdef ORE_DSI
00124
00125 if (l4dm_is_invalid_ds(conf->ro_send_ds))
00126 {
00127 LOG("sending via string ipc");
00128 descriptor_table[desc].send_func = ore_send_string;
00129 descriptor_table[desc].send_addr = NULL;
00130 }
00131 else
00132 {
00133 LOG("sending via dataspace");
00134 descriptor_table[desc].send_func = ore_send_dsi;
00135 __l4ore_init_send_socket(descriptor_table[desc].remote_manager_thread,
00136 conf, &send, &descriptor_table[desc].send_addr);
00137 }
00138
00139
00140 if (l4dm_is_invalid_ds(conf->ro_recv_ds))
00141 {
00142 LOG("receiving via string IPC");
00143 descriptor_table[desc].rx_func_blocking = ore_recv_string_blocking;
00144 descriptor_table[desc].rx_func_nonblocking = ore_recv_string_nonblocking;
00145 descriptor_table[desc].recv_addr = NULL;
00146 }
00147 else
00148 {
00149 LOG("receiving via dataspace");
00150 descriptor_table[desc].rx_func_blocking = ore_recv_dsi_blocking;
00151 descriptor_table[desc].rx_func_nonblocking = ore_recv_dsi_nonblocking;
00152 __l4ore_init_recv_socket(descriptor_table[desc].remote_manager_thread,
00153 conf, &receive, &descriptor_table[desc].recv_addr);
00154 }
00155
00156 descriptor_table[desc].local_send_socket = send;
00157 descriptor_table[desc].local_recv_socket = receive;
00158 #else
00159 descriptor_table[desc].rx_func_blocking = ore_recv_string_blocking;
00160 descriptor_table[desc].rx_func_nonblocking = ore_recv_string_nonblocking;
00161 descriptor_table[desc].send_func = ore_send_string;
00162 #endif
00163
00164 ret = ore_do_open(desc, device, mac, conf);
00165
00166 if (l4_is_invalid_id(ret))
00167 {
00168 #ifdef ORE_DSI
00169 if (l4dm_is_invalid_ds(conf->ro_send_ds) ||
00170 l4dm_is_invalid_ds(conf->ro_recv_ds))
00171 {
00172 LOG_Error("ore_open() returned INVALID_ID");
00173 release_descriptor(desc);
00174 return -1;
00175 }
00176 else
00177 {
00178 LOG("INVALID worker_id. this is ok, because we do rx/tx via DSI and need no worker.");
00179 }
00180 #else
00181 LOG_Error("ore_open() returned INVALID_ID");
00182 return -1;
00183 #endif
00184 }
00185
00186 #ifdef ORE_DSI
00187 if (!l4dm_is_invalid_ds(conf->ro_send_ds))
00188 {
00189 int iret = dsi_socket_connect(send, &conf->ro_send_ore_socketref);
00190 if (iret)
00191 {
00192 LOG_Error("send_socket socket connect");
00193
00194 return iret;
00195 }
00196 }
00197 if (!l4dm_is_invalid_ds(conf->ro_recv_ds))
00198 {
00199 int iret = dsi_socket_connect(receive, &conf->ro_recv_ore_socketref);
00200 if (iret)
00201 {
00202 LOG_Error("recv_socket socket connect");
00203
00204 return iret;
00205 }
00206 }
00207 #endif
00208
00209 descriptor_table[desc].remote_worker_thread = ret;
00210
00211 return desc;
00212 }
00213
00214 void l4ore_close(int handle)
00215 {
00216 ore_do_close(handle);
00217 }
00218
00219 int ore_lookup_server(char *orename, l4ore_handle_t *manager)
00220 {
00221 int i = 0;
00222
00223 while(i < ORE_NUM_LOOKUPS)
00224 {
00225 if (!names_waitfor_name(orename, manager, 10000))
00226 {
00227 LOG("Could not find ORe server '%s', %d. attempt.", orename, i + 1);
00228 i++;
00229 }
00230 else
00231 {
00232 LOG("ORe server %s = "l4util_idfmt, orename, l4util_idstr(*manager));
00233 return 0;
00234 }
00235 }
00236 LOG("Could not find ORe server '%s', aborting.", orename);
00237 return -1;
00238 }
00239