/* * Copyright (c) 2007 Josef Cejka * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include <../../../srv/devmap/devmap.h> #include "../tester.h" #include #define TEST_DEVICE1 "TestDevice1" #define TEST_DEVICE2 "TestDevice2" /** Handle requests from clients * */ static void driver_client_connection(ipc_callid_t iid, ipc_call_t *icall) { ipc_callid_t callid; ipc_call_t call; int retval; printf("connected: method=%u arg1=%u, arg2=%u arg3=%u.\n", IPC_GET_METHOD(*icall), IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall), IPC_GET_ARG3(*icall)); printf("driver_client_connection.\n"); ipc_answer_0(iid, EOK); /* Ignore parameters, the connection is already opened */ while (1) { callid = async_get_call(&call); retval = EOK; printf("method=%u arg1=%u, arg2=%u arg3=%u.\n", IPC_GET_METHOD(call), IPC_GET_ARG1(call), IPC_GET_ARG2(call), IPC_GET_ARG3(call)); switch (IPC_GET_METHOD(call)) { case IPC_M_PHONE_HUNGUP: /* TODO: Handle hangup */ return; default: printf("Unknown device method %u.\n", IPC_GET_METHOD(call)); retval = ENOENT; } ipc_answer_0(callid, retval); } return; } static int device_client_fibril(void *arg) { int handle; int device_phone; handle = (int)arg; device_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, \ DEVMAP_CONNECT_TO_DEVICE, handle); if (device_phone < 0) { printf("Failed to connect to devmap as client (handle = %u).\n", handle); return -1; } /* * device_phone = (int) IPC_GET_ARG3(answer); */ printf("Connected to device.\n"); ipc_call_sync_1_0(device_phone, 1024, 1025); /* * ipc_hangup(device_phone); */ ipc_hangup(device_phone); return EOK; } /** Communication test with device. * @param handle handle to tested instance. */ static int device_client(int handle) { /* fid_t fid; ipc_call_t call; ipc_callid_t callid; fid = fibril_create(device_client_fibril, (void *)handle); fibril_add_ready(fid); */ return EOK; } /** * */ static int driver_register(char *name) { ipcarg_t retval; aid_t req; ipc_call_t answer; int phone; ipcarg_t callback_phonehash; phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_DRIVER, 0); while (phone < 0) { usleep(100000); phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_DRIVER, 0); } req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer); retval = ipc_data_send(phone, (char *)name, strlen(name) + 1); if (retval != EOK) { async_wait_for(req, NULL); return -1; } async_set_client_connection(driver_client_connection); ipc_connect_to_me(phone, 0, 0, &callback_phonehash); /* if (NULL == async_new_connection(callback_phonehash, 0, NULL, driver_client_connection)) { printf("Failed to create new fibril.\n"); async_wait_for(req, NULL); return -1; } */ async_wait_for(req, &retval); printf("Driver '%s' registered.\n", name); return phone; } static int device_get_handle(int driver_phone, char *name, int *handle) { ipcarg_t retval; aid_t req; ipc_call_t answer; req = async_send_2(driver_phone, DEVMAP_DEVICE_GET_HANDLE, 0, 0, &answer); retval = ipc_data_send(driver_phone, name, strlen(name) + 1); if (retval != EOK) { printf("Failed to send device name '%s'.\n", name); async_wait_for(req, NULL); return retval; } async_wait_for(req, &retval); if (NULL != handle) { *handle = -1; } if (EOK == retval) { if (NULL != handle) { *handle = (int) IPC_GET_ARG1(answer); } printf("Device '%s' has handle %u.\n", name, (int) IPC_GET_ARG1(answer)); } else { printf("Failed to get handle for device '%s'.\n", name); } return retval; } /** Register new device. * @param driver_phone * @param name Device name. * @param handle Output variable. Handle to the created instance of device. */ static int device_register(int driver_phone, char *name, int *handle) { ipcarg_t retval; aid_t req; ipc_call_t answer; req = async_send_2(driver_phone, DEVMAP_DEVICE_REGISTER, 0, 0, &answer); retval = ipc_data_send(driver_phone, (char *)name, strlen(name) + 1); if (retval != EOK) { printf("Failed to send device name '%s'.\n", name); async_wait_for(req, NULL); return retval; } async_wait_for(req, &retval); if (NULL != handle) { *handle = -1; } if (EOK == retval) { if (NULL != handle) { *handle = (int) IPC_GET_ARG1(answer); } printf("Device registered with handle %u.\n", (int) IPC_GET_ARG1(answer)); } return retval; } /** Test DevMap from the driver's point of view. * * */ char * test_devmap1(bool quiet) { int driver_phone; int dev1_handle; int dev2_handle; int dev3_handle; int handle; /* Register new driver */ driver_phone = driver_register("TestDriver"); if (driver_phone < 0) { return "Error: Cannot register driver.\n"; } /* Register new device dev1*/ if (EOK != device_register(driver_phone, TEST_DEVICE1, &dev1_handle)) { ipc_hangup(driver_phone); return "Error: cannot register device.\n"; } /* Get handle for dev2 (Should fail unless device is already * registered by someone else) */ if (EOK == device_get_handle(driver_phone, TEST_DEVICE2, &handle)) { ipc_hangup(driver_phone); return "Error: got handle for dev2 before it was registered.\n"; } /* Register new device dev2*/ if (EOK != device_register(driver_phone, TEST_DEVICE2, &dev2_handle)) { ipc_hangup(driver_phone); return "Error: cannot register device dev2.\n"; } /* Register again device dev1 */ if (EOK == device_register(driver_phone, TEST_DEVICE1, &dev3_handle)) { return "Error: dev1 registered twice.\n"; } /* Get handle for dev1*/ if (EOK != device_get_handle(driver_phone, TEST_DEVICE1, &handle)) { ipc_hangup(driver_phone); return "Error: cannot get handle for 'DEVMAP_DEVICE1'.\n"; } if (handle != dev1_handle) { ipc_hangup(driver_phone); return "Error: cannot get handle for 'DEVMAP_DEVICE1'.\n"; } if (EOK != device_client(dev1_handle)) { ipc_hangup(driver_phone); return "Error: failed client test for 'DEVMAP_DEVICE1'.\n"; } /* TODO: */ ipc_hangup(driver_phone); return NULL; } char *test_devmap2(bool quiet) { /*TODO: Full automatic test */ return NULL; } char *test_devmap3(bool quiet) { /* TODO: allow user to call test functions in random order */ return NULL; }