Changeset cc574511 in mainline


Ignore:
Timestamp:
2011-08-16T12:37:58Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
16dc887
Parents:
86ffa27f
Message:

Basic category support in location service. Devman adds device services
to categories. Switch over input server device discovery from using
/dev/class to loc categories.

Files:
3 added
12 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ipc/sysipc.c

    r86ffa27f rcc574511  
    427427        case IPC_M_DATA_READ: {
    428428                size_t size = IPC_GET_ARG2(call->data);
    429                 if (size <= 0)
    430                         return ELIMIT;
    431429                if (size > DATA_XFER_LIMIT) {
    432430                        int flags = IPC_GET_ARG3(call->data);
  • uspace/lib/c/generic/loc.c

    r86ffa27f rcc574511  
    11/*
    22 * Copyright (c) 2007 Josef Cejka
    3  * Copyright (c) 2009 Jiri Svoboda
     3 * Copyright (c) 2011 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    331331}
    332332
     333/** Get category ID.
     334 *
     335 * Provided name of a category, return its ID.
     336 *
     337 * @param name          Category name
     338 * @param cat_id        Place to store ID
     339 * @param flags         IPC_FLAG_BLOCKING to wait for location service to start
     340 * @return              EOK on success or negative error code
     341 */
     342int loc_category_get_id(const char *name, category_id_t *cat_id,
     343    unsigned int flags)
     344{
     345        async_exch_t *exch;
     346       
     347        if (flags & IPC_FLAG_BLOCKING)
     348                exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
     349        else {
     350                exch = loc_exchange_begin(LOC_PORT_CONSUMER);
     351                if (exch == NULL)
     352                        return errno;
     353        }
     354       
     355        ipc_call_t answer;
     356        aid_t req = async_send_0(exch, LOC_CATEGORY_GET_ID,
     357            &answer);
     358        sysarg_t retval = async_data_write_start(exch, name, str_size(name));
     359       
     360        loc_exchange_end(exch);
     361       
     362        if (retval != EOK) {
     363                async_wait_for(req, NULL);
     364                return retval;
     365        }
     366       
     367        async_wait_for(req, &retval);
     368       
     369        if (retval != EOK) {
     370                if (cat_id != NULL)
     371                        *cat_id = (category_id_t) -1;
     372               
     373                return retval;
     374        }
     375       
     376        if (cat_id != NULL)
     377                *cat_id = (category_id_t) IPC_GET_ARG1(answer);
     378       
     379        return retval;
     380}
     381
     382
    333383loc_object_type_t loc_id_probe(service_id_t handle)
    334384{
     
    393443}
    394444
     445/** Add service to category.
     446 *
     447 * @param svc_id        Service ID
     448 * @param cat_id        Category ID
     449 * @return              EOK on success or negative error code
     450 */
     451int loc_service_add_to_cat(service_id_t svc_id, service_id_t cat_id)
     452{
     453        async_exch_t *exch;
     454        sysarg_t retval;
     455       
     456        exch = loc_exchange_begin_blocking(LOC_PORT_SUPPLIER);
     457        retval = async_req_2_0(exch, LOC_SERVICE_ADD_TO_CAT, svc_id, cat_id);
     458        loc_exchange_end(exch);
     459       
     460        return retval;
     461}
     462
    395463static size_t loc_count_services_internal(async_exch_t *exch,
    396464    service_id_t ns_handle)
     
    425493size_t loc_get_namespaces(loc_sdesc_t **data)
    426494{
    427         /* Loop until namespaces read succesful */
     495        /* Loop until read is succesful */
    428496        while (true) {
    429497                async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
     
    474542size_t loc_get_services(service_id_t ns_handle, loc_sdesc_t **data)
    475543{
    476         /* Loop until devices read succesful */
     544        /* Loop until read is succesful */
    477545        while (true) {
    478546                async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
     
    520588        }
    521589}
     590
     591static int loc_category_get_svcs_internal(category_id_t cat_id,
     592    service_id_t *id_buf, size_t buf_size, size_t *act_size)
     593{
     594        async_exch_t *exch = loc_exchange_begin_blocking(LOC_PORT_CONSUMER);
     595
     596        ipc_call_t answer;
     597        aid_t req = async_send_1(exch, LOC_CATEGORY_GET_SVCS, cat_id,
     598            &answer);
     599        int rc = async_data_read_start(exch, id_buf, buf_size);
     600       
     601        loc_exchange_end(exch);
     602       
     603        if (rc != EOK) {
     604                async_wait_for(req, NULL);
     605                return rc;
     606        }
     607       
     608        sysarg_t retval;
     609        async_wait_for(req, &retval);
     610       
     611        if (retval != EOK) {
     612                return retval;
     613        }
     614       
     615        *act_size = IPC_GET_ARG1(answer);
     616        return EOK;
     617}
     618
     619/** Get list of services in category.
     620 *
     621 * Returns an allocated array of service IDs.
     622 *
     623 * @param cat_id        Category ID
     624 * @param data          Place to store pointer to array of IDs
     625 * @param count         Place to store number of IDs
     626 * @return              EOK on success or negative error code
     627 */
     628int loc_category_get_svcs(category_id_t cat_id, category_id_t **data,
     629    size_t *count)
     630{
     631        service_id_t *ids;
     632        size_t act_size;
     633        size_t alloc_size;
     634        int rc;
     635
     636        *data = NULL;
     637        act_size = 0;   /* silence warning */
     638
     639        rc = loc_category_get_svcs_internal(cat_id, NULL, 0, &act_size);
     640        if (rc != EOK)
     641                return rc;
     642
     643        alloc_size = act_size;
     644        ids = malloc(alloc_size);
     645        if (ids == NULL)
     646                return ENOMEM;
     647
     648        while (true) {
     649                rc = loc_category_get_svcs_internal(cat_id, ids, alloc_size,
     650                    &act_size);
     651                if (rc != EOK)
     652                        return rc;
     653
     654                if (act_size <= alloc_size)
     655                        break;
     656
     657                alloc_size *= 2;
     658                free(ids);
     659
     660                ids = malloc(alloc_size);
     661                if (ids == NULL)
     662                        return ENOMEM;
     663        }
     664
     665        *count = act_size / sizeof(category_id_t);
     666        *data = ids;
     667        return EOK;
     668}
  • uspace/lib/c/include/ipc/loc.h

    r86ffa27f rcc574511  
    4040
    4141typedef sysarg_t service_id_t;
     42typedef sysarg_t category_id_t;
    4243
    4344typedef enum {
     
    5051        LOC_SERVER_REGISTER = IPC_FIRST_USER_METHOD,
    5152        LOC_SERVER_UNREGISTER,
     53        LOC_SERVICE_ADD_TO_CAT,
    5254        LOC_SERVICE_REGISTER,
    5355        LOC_SERVICE_UNREGISTER,
    5456        LOC_SERVICE_GET_ID,
    5557        LOC_NAMESPACE_GET_ID,
     58        LOC_CATEGORY_GET_ID,
     59        LOC_CATEGORY_GET_SVCS,
    5660        LOC_ID_PROBE,
    5761        LOC_NULL_CREATE,
  • uspace/lib/c/include/loc.h

    r86ffa27f rcc574511  
    4848extern int loc_service_register_with_iface(const char *, service_id_t *,
    4949    sysarg_t);
     50extern int loc_service_add_to_cat(service_id_t, category_id_t);
    5051
    5152extern int loc_service_get_id(const char *, service_id_t *,
     
    5354extern int loc_namespace_get_id(const char *, service_id_t *,
    5455    unsigned int);
     56extern int loc_category_get_id(const char *, category_id_t *,
     57    unsigned int);
     58extern int loc_category_get_svcs(category_id_t, category_id_t **, size_t *);
    5559extern loc_object_type_t loc_id_probe(service_id_t);
    5660
  • uspace/srv/devman/main.c

    r86ffa27f rcc574511  
    362362{
    363363        devman_handle_t handle = IPC_GET_ARG1(*call);
     364        category_id_t cat_id;
     365        int rc;
    364366       
    365367        /* Get class name. */
    366368        char *class_name;
    367         int rc = async_data_write_accept((void **) &class_name, true,
     369        rc = async_data_write_accept((void **) &class_name, true,
    368370            0, 0, 0, 0);
    369371        if (rc != EOK) {
     
    383385        /* Register the device's class alias with location service. */
    384386        loc_register_class_dev(class_info);
     387       
     388        rc = loc_category_get_id(class_name, &cat_id, IPC_FLAG_BLOCKING);
     389        if (rc == EOK) {
     390                loc_service_add_to_cat(fun->service_id, cat_id);
     391        } else {
     392                log_msg(LVL_ERROR, "Failed adding function `%s' to category "
     393                    "`%s'.", fun->pathname, class_name);
     394        }
    385395       
    386396        log_msg(LVL_NOTE, "Function `%s' added to class `%s' as `%s'.",
     
    760770        printf(NAME ": HelenOS Device Manager\n");
    761771
    762         if (log_init(NAME, LVL_ERROR) != EOK) {
     772        if (log_init(NAME, LVL_WARN) != EOK) {
    763773                printf(NAME ": Error initializing logging subsystem.\n");
    764774                return -1;
  • uspace/srv/hid/input/ctl/kbdev.c

    r86ffa27f rcc574511  
    4848#include <kbd_ctl.h>
    4949#include <kbd_port.h>
     50#include <loc.h>
    5051#include <stdlib.h>
     52#include <sys/typefmt.h>
    5153#include <vfs/vfs_sess.h>
    5254
     
    7072        /** Session with kbdev device */
    7173        async_sess_t *sess;
    72 
    73         /** File descriptor of open kbdev device */
    74         int fd;
    7574} kbdev_t;
    7675
     
    8483
    8584        kbdev->kbd_dev = kdev;
    86         kbdev->fd = -1;
    8785
    8886        return kbdev;
     
    9391        if (kbdev->sess != NULL)
    9492                async_hangup(kbdev->sess);
    95         if (kbdev->fd >= 0)
    96                 close(kbdev->fd);
    9793        free(kbdev);
    9894}
     
    10096static int kbdev_ctl_init(kbd_dev_t *kdev)
    10197{
    102         const char *pathname;
    10398        async_sess_t *sess;
    10499        async_exch_t *exch;
    105100        kbdev_t *kbdev;
    106         int fd;
     101        char *svc_name;
    107102        int rc;
    108103
    109         pathname = kdev->dev_path;
     104        if (asprintf(&svc_name, "devname%" PRIun, kdev->service_id) > 0)
     105                svc_name = (char *) "unknown";
    110106
    111         fd = open(pathname, O_RDWR);
    112         if (fd < 0) {
    113                 return -1;
    114         }
    115 
    116         sess = fd_session(EXCHANGE_SERIALIZE, fd);
     107        sess = loc_service_connect(EXCHANGE_SERIALIZE, kdev->service_id, 0);
    117108        if (sess == NULL) {
    118                 printf("%s: Failed starting session with '%s'\n", NAME, pathname);
    119                 close(fd);
     109                printf("%s: Failed starting session with '%s.'\n", NAME,
     110                    svc_name);
    120111                return -1;
    121112        }
     
    124115        if (kbdev == NULL) {
    125116                printf("%s: Failed allocating device structure for '%s'.\n",
    126                     NAME, pathname);
     117                    NAME, svc_name);
    127118                return -1;
    128119        }
    129120
    130         kbdev->fd = fd;
    131121        kbdev->sess = sess;
    132122
    133123        exch = async_exchange_begin(sess);
    134124        if (exch == NULL) {
    135                 printf("%s: Failed starting exchange with '%s'.\n", NAME, pathname);
     125                printf("%s: Failed starting exchange with '%s'.\n", NAME,
     126                    svc_name);
    136127                kbdev_destroy(kbdev);
    137128                return -1;
     
    141132        if (rc != EOK) {
    142133                printf("%s: Failed creating callback connection from '%s'.\n",
    143                     NAME, pathname);
     134                    NAME, svc_name);
    144135                async_exchange_end(exch);
    145136                kbdev_destroy(kbdev);
  • uspace/srv/hid/input/generic/input.c

    r86ffa27f rcc574511  
    3838
    3939#include <adt/list.h>
     40#include <bool.h>
    4041#include <ipc/services.h>
    4142#include <ipc/input.h>
     
    275276        kdev->port_ops = port;
    276277        kdev->ctl_ops = ctl;
    277         kdev->dev_path = NULL;
     278        kdev->service_id = 0;
    278279       
    279280        /* Initialize port driver. */
     
    303304        mdev->port_ops = port;
    304305        mdev->proto_ops = proto;
    305         mdev->dev_path = NULL;
     306        mdev->service_id = 0;
    306307       
    307308        /* Initialize port driver. */
     
    324325/** Add new kbdev device.
    325326 *
    326  * @param dev_path Filesystem path to the device (/loc/class/...)
     327 * @param service_id    Service ID of the keyboard device
    327328 *
    328329 */
    329 static int kbd_add_kbdev(const char *dev_path)
     330static int kbd_add_kbdev(service_id_t service_id)
    330331{
    331332        kbd_dev_t *kdev = kbd_dev_new();
     
    333334                return -1;
    334335       
    335         kdev->dev_path = dev_path;
     336        kdev->service_id = service_id;
    336337        kdev->port_ops = NULL;
    337338        kdev->ctl_ops = &kbdev_ctl;
     
    352353/** Add new mousedev device.
    353354 *
    354  * @param dev_path Filesystem path to the device (/loc/class/...)
     355 * @param service_id    Service ID of the mouse device
    355356 *
    356357 */
    357 static int mouse_add_mousedev(const char *dev_path)
     358static int mouse_add_mousedev(service_id_t service_id)
    358359{
    359360        mouse_dev_t *mdev = mouse_dev_new();
     
    361362                return -1;
    362363       
    363         mdev->dev_path = dev_path;
     364        mdev->service_id = service_id;
    364365        mdev->port_ops = NULL;
    365366        mdev->proto_ops = &mousedev_proto;
     
    487488 *
    488489 */
     490#include <sys/typefmt.h>
    489491static int dev_discovery_fibril(void *arg)
    490492{
    491         char *dev_path;
    492         size_t kbd_id = 1;
    493         size_t mouse_id = 1;
     493        category_id_t keyboard_cat, mouse_cat;
     494        service_id_t *svcs;
     495        size_t count, i;
     496        bool already_known;
     497        const char *dev_name = "todo";
    494498        int rc;
     499       
     500        rc = loc_category_get_id("keyboard", &keyboard_cat, IPC_FLAG_BLOCKING);
     501        if (rc != EOK) {
     502                printf("%s: Failed resolving category 'keyboard'.\n", NAME);
     503                return ENOENT;
     504        }
     505       
     506        rc = loc_category_get_id("mouse", &mouse_cat, IPC_FLAG_BLOCKING);
     507        if (rc != EOK) {
     508                printf("%s: Failed resolving category 'mouse'.\n", NAME);
     509                return ENOENT;
     510        }
    495511       
    496512        while (true) {
     
    498514               
    499515                /*
    500                  * Check for new keyboard device
     516                 * Check for new keyboard devices
    501517                 */
    502                 rc = asprintf(&dev_path, "/loc/class/keyboard\\%zu", kbd_id);
    503                 if (rc < 0)
     518                rc = loc_category_get_svcs(keyboard_cat, &svcs, &count);
     519                if (rc != EOK) {
     520                        printf("%s: Failed getting list of keyboard devices.\n",
     521                            NAME);
    504522                        continue;
    505                
    506                 if (kbd_add_kbdev(dev_path) == EOK) {
    507                         printf("%s: Connected keyboard device '%s'\n",
    508                             NAME, dev_path);
     523                }
     524
     525                for (i = 0; i < count; i++) {
     526                        already_known = false;
    509527                       
    510                         /* XXX Handle device removal */
    511                         ++kbd_id;
     528                        /* Determine whether we already know this device. */
     529                        list_foreach(kbd_devs, kdev_link) {
     530                                kbd_dev_t *kdev = list_get_instance(kdev_link,
     531                                    kbd_dev_t, kbd_devs);
     532                                if (kdev->service_id == svcs[i]) {
     533                                        already_known = true;
     534                                        break;
     535                                }
     536                        }
     537
     538                        if (!already_known) {
     539                                if (kbd_add_kbdev(svcs[i]) == EOK) {
     540                                        printf("%s: Connected keyboard device '%s'\n",
     541                                            NAME, dev_name);
     542                                }
     543                        }
    512544                }
    513545               
    514                 free(dev_path);
     546                /* XXX Handle device removal */
    515547               
    516548                /*
    517                  * Check for new mouse device
     549                 * Check for new mouse devices
    518550                 */
    519                 rc = asprintf(&dev_path, "/loc/class/mouse\\%zu", mouse_id);
    520                 if (rc < 0)
     551                rc = loc_category_get_svcs(mouse_cat, &svcs, &count);
     552                if (rc != EOK) {
     553                        printf("%s: Failed getting list of mouse devices.\n",
     554                            NAME);
    521555                        continue;
    522                
    523                 if (mouse_add_mousedev(dev_path) == EOK) {
    524                         printf("%s: Connected mouse device '%s'\n",
    525                             NAME, dev_path);
     556                }
     557
     558                for (i = 0; i < count; i++) {
     559                        already_known = false;
    526560                       
    527                         /* XXX Handle device removal */
    528                         ++mouse_id;
     561                        /* Determine whether we already know this device. */
     562                        list_foreach(mouse_devs, mdev_link) {
     563                                mouse_dev_t *mdev = list_get_instance(mdev_link,
     564                                    mouse_dev_t, mouse_devs);
     565                                if (mdev->service_id == svcs[i]) {
     566                                        already_known = true;
     567                                        break;
     568                                }
     569                        }
     570
     571                        if (!already_known) {
     572                                if (mouse_add_mousedev(svcs[i]) == EOK) {
     573                                        printf("%s: Connected mouse device '%s'\n",
     574                                            NAME, dev_name);
     575                                }
     576                        }
    529577                }
    530578               
    531                 free(dev_path);
     579                /* XXX Handle device removal */
    532580        }
    533581       
  • uspace/srv/hid/input/include/kbd.h

    r86ffa27f rcc574511  
    4040
    4141#include <adt/list.h>
     42#include <ipc/loc.h>
    4243
    4344struct kbd_port_ops;
     
    4950        link_t kbd_devs;
    5051
    51         /** Path to the device (only for kbdev devices) */
    52         const char *dev_path;
     52        /** Service ID (only for kbdev devices) */
     53        service_id_t service_id;
    5354
    5455        /** Port ops */
  • uspace/srv/hid/input/include/mouse.h

    r86ffa27f rcc574511  
    3939
    4040#include <adt/list.h>
     41#include <ipc/loc.h>
    4142
    4243struct mouse_port_ops;
     
    4748        link_t mouse_devs;
    4849       
    49         /** Path to the device (only for mouseev devices) */
    50         const char *dev_path;
     50        /** Service ID (only for mousedev devices) */
     51        service_id_t service_id;
    5152       
    5253        /** Port ops */
  • uspace/srv/hid/input/proto/mousedev.c

    r86ffa27f rcc574511  
    4444#include <ipc/mouseev.h>
    4545#include <input.h>
     46#include <loc.h>
    4647#include <mouse.h>
    4748#include <mouse_port.h>
    4849#include <mouse_proto.h>
     50#include <sys/typefmt.h>
    4951
    5052/** Mousedev softstate */
     
    5557        /** Session to mouse device */
    5658        async_sess_t *sess;
    57        
    58         /** File descriptor of open mousedev device */
    59         int fd;
    6059} mousedev_t;
    6160
     
    6766       
    6867        mousedev->mouse_dev = mdev;
    69         mousedev->fd = -1;
    7068       
    7169        return mousedev;
     
    7674        if (mousedev->sess != NULL)
    7775                async_hangup(mousedev->sess);
    78        
    79         if (mousedev->fd >= 0)
    80                 close(mousedev->fd);
    8176       
    8277        free(mousedev);
     
    122117static int mousedev_proto_init(mouse_dev_t *mdev)
    123118{
    124         const char *pathname = mdev->dev_path;
     119        char *svc_name;
    125120       
    126         int fd = open(pathname, O_RDWR);
    127         if (fd < 0)
    128                 return -1;
     121        if (asprintf(&svc_name, "devname%" PRIun, mdev->service_id) > 0)
     122                svc_name = (char *) "unknown";
    129123       
    130         async_sess_t *sess = fd_session(EXCHANGE_SERIALIZE, fd);
     124        async_sess_t *sess = loc_service_connect(EXCHANGE_SERIALIZE,
     125            mdev->service_id, 0);
    131126        if (sess == NULL) {
    132                 printf("%s: Failed starting session with '%s'\n", NAME, pathname);
    133                 close(fd);
     127                printf("%s: Failed starting session with '%s'\n", NAME, svc_name);
    134128                return -1;
    135129        }
     
    138132        if (mousedev == NULL) {
    139133                printf("%s: Failed allocating device structure for '%s'.\n",
    140                     NAME, pathname);
     134                    NAME, svc_name);
    141135                return -1;
    142136        }
    143137       
    144         mousedev->fd = fd;
    145138        mousedev->sess = sess;
    146139       
    147140        async_exch_t *exch = async_exchange_begin(sess);
    148141        if (exch == NULL) {
    149                 printf("%s: Failed starting exchange with '%s'.\n", NAME, pathname);
     142                printf("%s: Failed starting exchange with '%s'.\n", NAME,
     143                    svc_name);
    150144                mousedev_destroy(mousedev);
    151145                return -1;
     
    157151        if (rc != EOK) {
    158152                printf("%s: Failed creating callback connection from '%s'.\n",
    159                     NAME, pathname);
     153                    NAME, svc_name);
    160154                mousedev_destroy(mousedev);
    161155                return -1;
  • uspace/srv/loc/Makefile

    r86ffa27f rcc574511  
    3333
    3434SOURCES = \
     35        category.c \
    3536        loc.c
    3637
  • uspace/srv/loc/loc.c

    r86ffa27f rcc574511  
    4949#include <assert.h>
    5050
     51#include "category.h"
     52#include "loc.h"
     53
    5154#define NAME          "loc"
    5255#define NULL_SERVICES  256
    53 
    54 /** Representation of server (supplier).
    55  *
    56  * Each server supplies a set of services.
    57  *
    58  */
    59 typedef struct {
    60         /** Link to servers_list */
    61         link_t servers;
    62        
    63         /** List of services supplied by this server */
    64         list_t services;
    65        
    66         /** Session asociated with this server */
    67         async_sess_t *sess;
    68        
    69         /** Server name */
    70         char *name;
    71        
    72         /** Fibril mutex for list of services owned by this server */
    73         fibril_mutex_t services_mutex;
    74 } loc_server_t;
    75 
    76 /** Info about registered namespaces
    77  *
    78  */
    79 typedef struct {
    80         /** Link to namespaces_list */
    81         link_t namespaces;
    82        
    83         /** Unique namespace identifier */
    84         service_id_t id;
    85        
    86         /** Namespace name */
    87         char *name;
    88        
    89         /** Reference count */
    90         size_t refcnt;
    91 } loc_namespace_t;
    92 
    93 /** Info about registered service
    94  *
    95  */
    96 typedef struct {
    97         /** Link to global list of services (services_list) */
    98         link_t services;
    99         /** Link to server list of services (loc_server_t.services) */
    100         link_t server_services;
    101         /** Unique service identifier */
    102         service_id_t id;
    103         /** Service namespace */
    104         loc_namespace_t *namespace;
    105         /** Service name */
    106         char *name;
    107         /** Supplier of this service */
    108         loc_server_t *server;
    109         /** Use this interface when forwarding to server. */
    110         sysarg_t forward_interface;
    111 } loc_service_t;
    11256
    11357LIST_INITIALIZE(services_list);
     
    13781static LIST_INITIALIZE(dummy_null_services);
    13882
    139 static service_id_t loc_create_id(void)
     83/** Service directory ogranized by categories (yellow pages) */
     84static categ_dir_t cdir;
     85
     86service_id_t loc_create_id(void)
    14087{
    14188        /* TODO: allow reusing old ids after their unregistration
     
    734681}
    735682
     683/** Find ID for category specified by name.
     684 *
     685 * On success, answer will contain EOK int retval and service ID in arg1.
     686 * On failure, error code will be sent in retval.
     687 *
     688 */
     689static void loc_category_get_id(ipc_callid_t iid, ipc_call_t *icall)
     690{
     691        char *name;
     692        category_t *cat;
     693       
     694        /* Get service name */
     695        int rc = async_data_write_accept((void **) &name, true, 0,
     696            LOC_NAME_MAXLEN, 0, NULL);
     697        if (rc != EOK) {
     698                async_answer_0(iid, rc);
     699                return;
     700        }
     701       
     702        fibril_mutex_lock(&cdir.mutex);
     703
     704        cat = category_find_by_name(&cdir, name);
     705        if (cat == NULL) {
     706                /* Category not found */
     707                async_answer_0(iid, ENOENT);
     708                goto cleanup;
     709        }
     710       
     711        async_answer_1(iid, EOK, cat->id);
     712cleanup:
     713        fibril_mutex_unlock(&cdir.mutex);
     714        free(name);
     715}
     716
    736717static void loc_id_probe(ipc_callid_t iid, ipc_call_t *icall)
    737718{
     
    892873}
    893874
     875static void loc_category_get_svcs(ipc_callid_t iid, ipc_call_t *icall)
     876{
     877        ipc_callid_t callid;
     878        size_t size;
     879        size_t act_size;
     880        int rc;
     881       
     882        if (!async_data_read_receive(&callid, &size)) {
     883                async_answer_0(callid, EREFUSED);
     884                async_answer_0(iid, EREFUSED);
     885                return;
     886        }
     887       
     888        fibril_mutex_lock(&cdir.mutex);
     889       
     890        category_t *cat = category_get(&cdir, IPC_GET_ARG1(*icall));
     891        if (cat == NULL) {
     892                fibril_mutex_unlock(&cdir.mutex);
     893                async_answer_0(callid, ENOENT);
     894                async_answer_0(iid, ENOENT);
     895                return;
     896        }
     897       
     898        category_id_t *id_buf = (category_id_t *) malloc(size);
     899        if (id_buf == NULL) {
     900                fibril_mutex_unlock(&cdir.mutex);
     901                async_answer_0(callid, ENOMEM);
     902                async_answer_0(iid, ENOMEM);
     903                return;
     904        }
     905       
     906        fibril_mutex_lock(&cat->mutex);
     907       
     908        rc = category_get_services(cat, id_buf, size, &act_size);
     909        if (rc != EOK) {
     910                fibril_mutex_unlock(&cat->mutex);
     911                fibril_mutex_unlock(&cdir.mutex);
     912                async_answer_0(callid, rc);
     913                async_answer_0(iid, rc);
     914                return;
     915        }
     916       
     917        fibril_mutex_unlock(&cat->mutex);
     918        fibril_mutex_unlock(&cdir.mutex);
     919       
     920        sysarg_t retval = async_data_read_finalize(callid, id_buf, size);
     921        free(id_buf);
     922       
     923        async_answer_1(iid, retval, act_size);
     924}
     925
     926
    894927static void loc_null_create(ipc_callid_t iid, ipc_call_t *icall)
    895928{
     
    9911024}
    9921025
     1026static void loc_service_add_to_cat(ipc_callid_t iid, ipc_call_t *icall)
     1027{
     1028        category_t *cat;
     1029        loc_service_t *svc;
     1030        catid_t cat_id;
     1031        service_id_t svc_id;
     1032        sysarg_t retval;
     1033       
     1034        svc_id = IPC_GET_ARG1(*icall);
     1035        cat_id = IPC_GET_ARG2(*icall);
     1036       
     1037        fibril_mutex_lock(&services_list_mutex);
     1038        fibril_mutex_lock(&cdir.mutex);
     1039       
     1040        cat = category_get(&cdir, cat_id);
     1041        svc = loc_service_find_id(svc_id);
     1042       
     1043        fibril_mutex_lock(&cat->mutex);
     1044        retval = category_add_service(cat, svc);
     1045
     1046        fibril_mutex_unlock(&cat->mutex);
     1047        fibril_mutex_unlock(&cdir.mutex);
     1048        fibril_mutex_unlock(&services_list_mutex);
     1049
     1050        async_answer_0(iid, retval);
     1051}
     1052
     1053
    9931054/** Initialize location service.
    9941055 *
     
    9971058static bool loc_init(void)
    9981059{
    999         fibril_mutex_lock(&null_services_mutex);
    1000        
    10011060        unsigned int i;
     1061        category_t *cat;
     1062
    10021063        for (i = 0; i < NULL_SERVICES; i++)
    10031064                null_services[i] = NULL;
    10041065       
    1005         fibril_mutex_unlock(&null_services_mutex);
    1006        
     1066        categ_dir_init(&cdir);
     1067
     1068        cat = category_new("bd");
     1069        categ_dir_add_cat(&cdir, cat);
     1070
     1071        cat = category_new("keyboard");
     1072        categ_dir_add_cat(&cdir, cat);
     1073
     1074        cat = category_new("mouse");
     1075        categ_dir_add_cat(&cdir, cat);
     1076
     1077        cat = category_new("serial");
     1078        categ_dir_add_cat(&cdir, cat);
     1079
    10071080        return true;
    10081081}
     
    10341107                                async_answer_0(callid, EOK);
    10351108                        break;
     1109                case LOC_SERVICE_ADD_TO_CAT:
     1110                        /* Add service to category */
     1111                        loc_service_add_to_cat(callid, &call);
     1112                        break;
    10361113                case LOC_SERVICE_REGISTER:
    10371114                        /* Register one service */
     
    10831160                case LOC_NAMESPACE_GET_ID:
    10841161                        loc_namespace_get_id(callid, &call);
     1162                        break;
     1163                case LOC_CATEGORY_GET_ID:
     1164                        loc_category_get_id(callid, &call);
     1165                        break;
     1166                case LOC_CATEGORY_GET_SVCS:
     1167                        loc_category_get_svcs(callid, &call);
    10851168                        break;
    10861169                case LOC_ID_PROBE:
Note: See TracChangeset for help on using the changeset viewer.