Changeset 24ab58b3 in mainline for uspace/srv/net/net/net.c


Ignore:
Timestamp:
2010-04-06T11:41:48Z (14 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
14f1db0
Parents:
4dd8529
Message:

more compact network startup messages (usually one line instead of multiple lines)
pass module name as an argument to nil_message() and friends
deeper cstyle changes (replace forward prototypes with proper extern declarations and static functions, change doxygen comments, stick more closely to the 80-column rule, no argument names in header files, spacing, comments, etc.)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/net/net.c

    r4dd8529 r24ab58b3  
    2828
    2929/** @addtogroup net
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Networking subsystem central module implementation.
     34 * Networking subsystem central module implementation.
     35 *
    3536 */
    3637
     
    6465#include "net.h"
    6566
     67/** Networking module name.
     68 *
     69 */
     70#define NAME  "net"
     71
    6672/** File read buffer size.
    67  */
    68 #define BUFFER_SIZE     256
    69 
    70 /** Networking module name.
    71  */
    72 #define NAME    "Networking"
     73 *
     74 */
     75#define BUFFER_SIZE  256
    7376
    7477/** Networking module global data.
    75  */
    76 net_globals_t   net_globals;
    77 
    78 /** Generates new system-unique device identifier.
    79  *  @returns The system-unique devic identifier.
    80  */
    81 device_id_t generate_new_device_id(void);
    82 
    83 /** Returns the configured values.
    84  *  The network interface configuration is searched first.
    85  *  @param[in] netif_conf The network interface configuration setting.
    86  *  @param[out] configuration The found configured values.
    87  *  @param[in] count The desired settings count.
    88  *  @param[out] data The found configuration settings data.
    89  *  @returns EOK.
    90  */
    91 int net_get_conf(measured_strings_ref netif_conf, measured_string_ref configuration, size_t count, char ** data);
    92 
    93 /** Initializes the networking module.
    94  *  @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.
    95  *  @returns EOK on success.
    96  *  @returns ENOMEM if there is not enough memory left.
    97  */
    98 int net_initialize(async_client_conn_t client_connection);
    99 
    100 /** \todo
    101  */
    102 int parse_line(measured_strings_ref configuration, char * line);
    103 
    104 /** Reads the networking subsystem global configuration.
    105  *  @returns EOK on success.
    106  *  @returns Other error codes as defined for the add_configuration() function.
    107  */
    108 int read_configuration(void);
    109 
    110 /** \todo
    111  */
    112 int read_configuration_file(const char * directory, const char * filename, measured_strings_ref configuration);
    113 
    114 /** Reads the network interface specific configuration.
    115  *  @param[in] name The network interface name.
    116  *  @param[in,out] netif The network interface structure.
    117  *  @returns EOK on success.
    118  *  @returns Other error codes as defined for the add_configuration() function.
    119  */
    120 int read_netif_configuration(const char * name, netif_ref netif);
    121 
    122 /** Starts the network interface according to its configuration.
    123  *  Registers the network interface with the subsystem modules.
    124  *  Starts the needed subsystem modules.
    125  *  @param[in] netif The network interface specific data.
    126  *  @returns EOK on success.
    127  *  @returns EINVAL if there are some settings missing.
    128  *  @returns ENOENT if the internet protocol module is not known.
    129  *  @returns Other error codes as defined for the netif_probe_req() function.
    130  *  @returns Other error codes as defined for the nil_device_req() function.
    131  *  @returns Other error codes as defined for the needed internet layer registering function.
    132  */
    133 int start_device(netif_ref netif);
    134 
    135 /** Reads the configuration and starts all network interfaces.
    136  *  @returns EOK on success.
    137  *  @returns EXDEV if there is no available system-unique device identifier.
    138  *  @returns EINVAL if any of the network interface names are not configured.
    139  *  @returns ENOMEM if there is not enough memory left.
    140  *  @returns Other error codes as defined for the read_configuration() function.
    141  *  @returns Other error codes as defined for the read_netif_configuration() function.
    142  *  @returns Other error codes as defined for the start_device() function.
    143  */
    144 int startup(void);
    145 
    146 GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t)
    147 
    148 DEVICE_MAP_IMPLEMENT(netifs, netif_t)
    149 
    150 int add_configuration(measured_strings_ref configuration, const char * name, const char * value){
    151         ERROR_DECLARE;
    152 
    153         measured_string_ref setting;
    154 
    155         setting = measured_string_create_bulk(value, 0);
    156         if(! setting){
     78 *
     79 */
     80net_globals_t net_globals;
     81
     82GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t);
     83DEVICE_MAP_IMPLEMENT(netifs, netif_t);
     84
     85/** Add the configured setting to the configuration map.
     86 *
     87 * @param[in] configuration The configuration map.
     88 * @param[in] name          The setting name.
     89 * @param[in] value         The setting value.
     90 *
     91 * @returns EOK on success.
     92 * @returns ENOMEM if there is not enough memory left.
     93 *
     94 */
     95int add_configuration(measured_strings_ref configuration, const char *name,
     96    const char *value)
     97{
     98        ERROR_DECLARE;
     99       
     100        measured_string_ref setting =
     101            measured_string_create_bulk(value, 0);
     102       
     103        if (!setting)
    157104                return ENOMEM;
    158         }
    159         // add the configuration setting
    160         if(ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))){
     105       
     106        /* Add the configuration setting */
     107        if (ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))) {
    161108                free(setting);
    162109                return ERROR_CODE;
    163110        }
    164         return EOK;
    165 }
    166 
    167 device_id_t generate_new_device_id(void){
     111       
     112        return EOK;
     113}
     114
     115/** Generate new system-unique device identifier.
     116 *
     117 * @returns The system-unique devic identifier.
     118 *
     119 */
     120static device_id_t generate_new_device_id(void)
     121{
    168122        return device_assign_devno();
    169123}
    170124
    171 /** Starts the networking module.
    172  *  Initializes the client connection serving function, initializes the module, registers the module service and starts the async manager, processing IPC messages in an infinite loop.
    173  *  @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.
    174  *  @returns EOK on successful module termination.
    175  *  @returns Other error codes as defined for the net_initialize() function.
    176  *  @returns Other error codes as defined for the REGISTER_ME() macro function.
    177  */
    178 static int net_module_start(async_client_conn_t client_connection){
    179         ERROR_DECLARE;
    180 
    181         ipcarg_t phonehash;
    182 
    183         async_set_client_connection(client_connection);
    184         ERROR_PROPAGATE(pm_init());
    185         if(ERROR_OCCURRED(net_initialize(client_connection))
    186                 || ERROR_OCCURRED(REGISTER_ME(SERVICE_NETWORKING, &phonehash))){
    187                 pm_destroy();
     125static int parse_line(measured_strings_ref configuration, char *line)
     126{
     127        ERROR_DECLARE;
     128       
     129        /* From the beginning */
     130        char *name = line;
     131       
     132        /* Skip comments and blank lines */
     133        if ((*name == '#') || (*name == '\0'))
     134                return EOK;
     135       
     136        /* Skip spaces */
     137        while (isspace(*name))
     138                name++;
     139       
     140        /* Remember the name start */
     141        char *value = name;
     142       
     143        /* Skip the name */
     144        while (isalnum(*value) || (*value == '_'))
     145                value++;
     146       
     147        if (*value == '=') {
     148                /* Terminate the name */
     149                *value = '\0';
     150        } else {
     151                /* Terminate the name */
     152                *value = '\0';
     153               
     154                /* Skip until '=' */
     155                value++;
     156                while ((*value) && (*value != '='))
     157                        value++;
     158               
     159                /* Not found? */
     160                if (*value != '=')
     161                        return EINVAL;
     162        }
     163       
     164        value++;
     165       
     166        /* Skip spaces */
     167        while (isspace(*value))
     168                value++;
     169       
     170        /* Create a bulk measured string till the end */
     171        measured_string_ref setting =
     172            measured_string_create_bulk(value, 0);
     173        if (!setting)
     174                return ENOMEM;
     175       
     176        /* Add the configuration setting */
     177        if (ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))) {
     178                free(setting);
    188179                return ERROR_CODE;
    189180        }
    190 
    191         async_manager();
    192 
    193         pm_destroy();
    194         return EOK;
    195 }
    196 
    197 int net_connect_module(services_t service){
    198         return EOK;
    199 }
    200 
    201 void net_free_settings(measured_string_ref settings, char * data){
    202 }
    203 
    204 int net_get_conf(measured_strings_ref netif_conf, measured_string_ref configuration, size_t count, char ** data){
    205         measured_string_ref setting;
    206         size_t index;
    207 
    208         if(data){
    209                 *data = NULL;
    210         }
    211 
    212         for(index = 0; index < count; ++ index){
    213                 setting = measured_strings_find(netif_conf, configuration[index].value, 0);
    214                 if(! setting){
    215                         setting = measured_strings_find(&net_globals.configuration, configuration[index].value, 0);
     181       
     182        return EOK;
     183}
     184
     185static int read_configuration_file(const char *directory, const char *filename,
     186    measured_strings_ref configuration)
     187{
     188        ERROR_DECLARE;
     189       
     190        printf("%s: Reading configuration file %s/%s\n", NAME, directory, filename);
     191       
     192        /* Construct the full filename */
     193        char line[BUFFER_SIZE];
     194        if (snprintf(line, BUFFER_SIZE, "%s/%s", directory, filename) > BUFFER_SIZE)
     195                return EOVERFLOW;
     196       
     197        /* Open the file */
     198        FILE *cfg = fopen(line, "r");
     199        if (!cfg)
     200                return ENOENT;
     201       
     202        /*
     203         * Read the configuration line by line
     204         * until an error or the end of file
     205         */
     206        unsigned int line_number = 0;
     207        size_t index = 0;
     208        while ((!ferror(cfg)) && (!feof(cfg))) {
     209                int read = fgetc(cfg);
     210                if ((read > 0) && (read != '\n') && (read != '\r')) {
     211                        if (index >= BUFFER_SIZE) {
     212                                line[BUFFER_SIZE - 1] = '\0';
     213                                fprintf(stderr, "%s: Configuration line %u too long: %s\n",
     214                                    NAME, line_number, line);
     215                               
     216                                /* No space left in the line buffer */
     217                                return EOVERFLOW;
     218                        } else {
     219                                /* Append the character */
     220                                line[index] = (char) read;
     221                                index++;
     222                        }
     223                } else {
     224                        /* On error or new line */
     225                        line[index] = '\0';
     226                        line_number++;
     227                        if (ERROR_OCCURRED(parse_line(configuration, line)))
     228                                fprintf(stderr, "%s: Configuration error on line %u: %s\n",
     229                                    NAME, line_number, line);
     230                       
     231                        index = 0;
    216232                }
    217                 if(setting){
    218                         configuration[index].length = setting->length;
    219                         configuration[index].value = setting->value;
    220                 }else{
    221                         configuration[index].length = 0;
    222                         configuration[index].value = NULL;
    223                 }
    224         }
    225         return EOK;
    226 }
    227 
    228 int net_get_conf_req(int net_phone, measured_string_ref * configuration, size_t count, char ** data){
    229         if(!(configuration && (count > 0))){
    230                 return EINVAL;
    231         }
    232 
    233         return net_get_conf(NULL, * configuration, count, data);
    234 }
    235 
    236 int net_get_device_conf_req(int net_phone, device_id_t device_id, measured_string_ref * configuration, size_t count, char ** data){
    237         netif_ref netif;
    238 
    239         if(!(configuration && (count > 0))){
    240                 return EINVAL;
    241         }
    242 
    243         netif = netifs_find(&net_globals.netifs, device_id);
    244         if(netif){
    245                 return net_get_conf(&netif->configuration, * configuration, count, data);
    246         }else{
    247                 return net_get_conf(NULL, * configuration, count, data);
    248         }
    249 }
    250 
    251 int net_initialize(async_client_conn_t client_connection){
    252         ERROR_DECLARE;
    253 
     233        }
     234       
     235        fclose(cfg);
     236        return EOK;
     237}
     238
     239/** Read the network interface specific configuration.
     240 *
     241 * @param[in]     name  The network interface name.
     242 * @param[in,out] netif The network interface structure.
     243 *
     244 * @returns EOK on success.
     245 * @returns Other error codes as defined for the add_configuration() function.
     246 *
     247 */
     248static int read_netif_configuration(const char *name, netif_t *netif)
     249{
     250        return read_configuration_file(CONF_DIR, name, &netif->configuration);
     251}
     252
     253/** Read the networking subsystem global configuration.
     254 *
     255 * @returns EOK on success.
     256 * @returns Other error codes as defined for the add_configuration() function.
     257 *
     258 */
     259static int read_configuration(void)
     260{
     261        return read_configuration_file(CONF_DIR, CONF_GENERAL_FILE,
     262            &net_globals.configuration);
     263}
     264
     265/** Initialize the networking module.
     266 *
     267 * @param[in] client_connection The client connection processing
     268 *                              function. The module skeleton propagates
     269 *                              its own one.
     270 *
     271 * @returns EOK on success.
     272 * @returns ENOMEM if there is not enough memory left.
     273 *
     274 */
     275static int net_initialize(async_client_conn_t client_connection)
     276{
     277        ERROR_DECLARE;
     278       
    254279        netifs_initialize(&net_globals.netifs);
    255280        char_map_initialize(&net_globals.netif_names);
    256281        modules_initialize(&net_globals.modules);
    257282        measured_strings_initialize(&net_globals.configuration);
    258 
    259         // TODO dynamic configuration
     283       
     284        // TODO: dynamic configuration
    260285        ERROR_PROPAGATE(read_configuration());
    261 
    262         ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, LO_NAME, LO_FILENAME, SERVICE_LO, 0, connect_to_service));
    263         ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, DP8390_NAME, DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service));
    264         ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, ETHERNET_NAME, ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service));
    265         ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, NILDUMMY_NAME, NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service));
    266 
    267         // build specific initialization
     286       
     287        ERROR_PROPAGATE(add_module(NULL, &net_globals.modules,
     288            LO_NAME, LO_FILENAME, SERVICE_LO, 0, connect_to_service));
     289        ERROR_PROPAGATE(add_module(NULL, &net_globals.modules,
     290            DP8390_NAME, DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service));
     291        ERROR_PROPAGATE(add_module(NULL, &net_globals.modules,
     292            ETHERNET_NAME, ETHERNET_FILENAME, SERVICE_ETHERNET, 0,
     293            connect_to_service));
     294        ERROR_PROPAGATE(add_module(NULL, &net_globals.modules,
     295            NILDUMMY_NAME, NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0,
     296            connect_to_service));
     297       
     298        /* Build specific initialization */
    268299        return net_initialize_build(client_connection);
    269300}
    270301
    271 int net_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
    272         ERROR_DECLARE;
    273 
     302/** Start the networking module.
     303 *
     304 * Initializes the client connection serving function,
     305 * initializes the module, registers the module service
     306 * and starts the async manager, processing IPC messages
     307 * in an infinite loop.
     308 *
     309 * @param[in] client_connection The client connection
     310 *                              processing function. The
     311 *                              module skeleton propagates
     312 *                              its own one.
     313 *
     314 * @returns EOK on successful module termination.
     315 * @returns Other error codes as defined for the net_initialize() function.
     316 * @returns Other error codes as defined for the REGISTER_ME() macro function.
     317 *
     318 */
     319static int net_module_start(async_client_conn_t client_connection)
     320{
     321        ERROR_DECLARE;
     322       
     323        async_set_client_connection(client_connection);
     324        ERROR_PROPAGATE(pm_init());
     325       
     326        ipcarg_t phonehash;
     327       
     328        if (ERROR_OCCURRED(net_initialize(client_connection))
     329            || ERROR_OCCURRED(REGISTER_ME(SERVICE_NETWORKING, &phonehash))){
     330                pm_destroy();
     331                return ERROR_CODE;
     332        }
     333       
     334        async_manager();
     335       
     336        pm_destroy();
     337        return EOK;
     338}
     339
     340/** Return the configured values.
     341 *
     342 * The network interface configuration is searched first.
     343 &
     344 * @param[in]  netif_conf    The network interface configuration setting.
     345 * @param[out] configuration The found configured values.
     346 * @param[in]  count         The desired settings count.
     347 * @param[out] data          The found configuration settings data.
     348 *
     349 * @returns EOK.
     350 *
     351 */
     352static int net_get_conf(measured_strings_ref netif_conf,
     353    measured_string_ref configuration, size_t count, char **data)
     354{
     355        if (data)
     356                *data = NULL;
     357       
     358        size_t index;
     359        for (index = 0; index < count; index++) {
     360                measured_string_ref setting =
     361                    measured_strings_find(netif_conf, configuration[index].value, 0);
     362                if (!setting)
     363                        setting = measured_strings_find(&net_globals.configuration,
     364                            configuration[index].value, 0);
     365               
     366                if (setting) {
     367                        configuration[index].length = setting->length;
     368                        configuration[index].value = setting->value;
     369                } else {
     370                        configuration[index].length = 0;
     371                        configuration[index].value = NULL;
     372                }
     373        }
     374       
     375        return EOK;
     376}
     377
     378int net_get_conf_req(int net_phone, measured_string_ref *configuration,
     379    size_t count, char **data)
     380{
     381        if (!(configuration && (count > 0)))
     382                return EINVAL;
     383       
     384        return net_get_conf(NULL, *configuration, count, data);
     385}
     386
     387int net_get_device_conf_req(int net_phone, device_id_t device_id,
     388    measured_string_ref *configuration, size_t count, char **data)
     389{
     390        if ((!configuration) || (count == 0))
     391                return EINVAL;
     392
     393        netif_t *netif = netifs_find(&net_globals.netifs, device_id);
     394        if (netif)
     395                return net_get_conf(&netif->configuration, *configuration, count, data);
     396        else
     397                return net_get_conf(NULL, *configuration, count, data);
     398}
     399
     400void net_free_settings(measured_string_ref settings, char *data)
     401{
     402}
     403
     404/** Start the network interface according to its configuration.
     405 *
     406 * Register the network interface with the subsystem modules.
     407 * Start the needed subsystem modules.
     408 *
     409 * @param[in] netif The network interface specific data.
     410 *
     411 * @returns EOK on success.
     412 * @returns EINVAL if there are some settings missing.
     413 * @returns ENOENT if the internet protocol module is not known.
     414 * @returns Other error codes as defined for the netif_probe_req() function.
     415 * @returns Other error codes as defined for the nil_device_req() function.
     416 * @returns Other error codes as defined for the needed internet layer
     417 *          registering function.
     418 *
     419 */
     420static int start_device(netif_t *netif)
     421{
     422        ERROR_DECLARE;
     423       
     424        /* Mandatory netif */
     425        measured_string_ref setting =
     426            measured_strings_find(&netif->configuration, CONF_NETIF, 0);
     427       
     428        netif->driver = get_running_module(&net_globals.modules, setting->value);
     429        if (!netif->driver) {
     430                fprintf(stderr, "%s: Failed to start network interface driver '%s'\n",
     431                    NAME, setting->value);
     432                return EINVAL;
     433        }
     434       
     435        /* Optional network interface layer */
     436        setting = measured_strings_find(&netif->configuration, CONF_NIL, 0);
     437        if (setting) {
     438                netif->nil = get_running_module(&net_globals.modules, setting->value);
     439                if (!netif->nil) {
     440                        fprintf(stderr, "%s: Failed to start network interface layer '%s'\n",
     441                            NAME, setting->value);
     442                        return EINVAL;
     443                }
     444        } else
     445                netif->nil = NULL;
     446       
     447        /* Mandatory internet layer */
     448        setting = measured_strings_find(&netif->configuration, CONF_IL, 0);
     449        netif->il = get_running_module(&net_globals.modules, setting->value);
     450        if (!netif->il) {
     451                fprintf(stderr, "%s: Failed to start internet layer '%s'\n",
     452                    NAME, setting->value);
     453                return EINVAL;
     454        }
     455       
     456        /* Hardware configuration */
     457        setting = measured_strings_find(&netif->configuration, CONF_IRQ, 0);
     458        int irq = setting ? strtol(setting->value, NULL, 10) : 0;
     459       
     460        setting = measured_strings_find(&netif->configuration, CONF_IO, 0);
     461        int io = setting ? strtol(setting->value, NULL, 16) : 0;
     462       
     463        ERROR_PROPAGATE(netif_probe_req(netif->driver->phone, netif->id, irq, io));
     464       
     465        /* Network interface layer startup */
     466        services_t internet_service;
     467        if (netif->nil) {
     468                setting = measured_strings_find(&netif->configuration, CONF_MTU, 0);
     469                if (!setting)
     470                        setting = measured_strings_find(&net_globals.configuration,
     471                            CONF_MTU, 0);
     472               
     473                int mtu = setting ? strtol(setting->value, NULL, 10) : 0;
     474               
     475                ERROR_PROPAGATE(nil_device_req(netif->nil->phone, netif->id, mtu,
     476                    netif->driver->service));
     477               
     478                internet_service = netif->nil->service;
     479        } else
     480                internet_service = netif->driver->service;
     481       
     482        /* Inter-network layer startup */
     483        switch (netif->il->service) {
     484                case SERVICE_IP:
     485                        ERROR_PROPAGATE(ip_device_req(netif->il->phone, netif->id,
     486                            internet_service));
     487                        break;
     488                default:
     489                        return ENOENT;
     490        }
     491       
     492        ERROR_PROPAGATE(netif_start_req(netif->driver->phone, netif->id));
     493        return EOK;
     494}
     495
     496/** Read the configuration and start all network interfaces.
     497 *
     498 * @returns EOK on success.
     499 * @returns EXDEV if there is no available system-unique device identifier.
     500 * @returns EINVAL if any of the network interface names are not configured.
     501 * @returns ENOMEM if there is not enough memory left.
     502 * @returns Other error codes as defined for the read_configuration()
     503 *          function.
     504 * @returns Other error codes as defined for the read_netif_configuration()
     505 *          function.
     506 * @returns Other error codes as defined for the start_device() function.
     507 *
     508 */
     509static int startup(void)
     510{
     511        ERROR_DECLARE;
     512       
     513        const char *conf_files[] = {"lo", "ne2k"};
     514        size_t count = sizeof(conf_files) / sizeof(char *);
     515       
     516        size_t i;
     517        for (i = 0; i < count; i++) {
     518                netif_t *netif = (netif_t *) malloc(sizeof(netif_t));
     519                if (!netif)
     520                        return ENOMEM;
     521               
     522                netif->id = generate_new_device_id();
     523                if (!netif->id)
     524                        return EXDEV;
     525               
     526                ERROR_PROPAGATE(measured_strings_initialize(&netif->configuration));
     527               
     528                /* Read configuration files */
     529                if (ERROR_OCCURRED(read_netif_configuration(conf_files[i], netif))) {
     530                        measured_strings_destroy(&netif->configuration);
     531                        free(netif);
     532                        return ERROR_CODE;
     533                }
     534               
     535                /* Mandatory name */
     536                measured_string_ref setting =
     537                    measured_strings_find(&netif->configuration, CONF_NAME, 0);
     538                if (!setting) {
     539                        fprintf(stderr, "%s: Network interface name is missing\n", NAME);
     540                        measured_strings_destroy(&netif->configuration);
     541                        free(netif);
     542                        return EINVAL;
     543                }
     544                netif->name = setting->value;
     545               
     546                /* Add to the netifs map */
     547                int index = netifs_add(&net_globals.netifs, netif->id, netif);
     548                if (index < 0) {
     549                        measured_strings_destroy(&netif->configuration);
     550                        free(netif);
     551                        return index;
     552                }
     553               
     554                /*
     555                 * Add to the netif names map and start network interfaces
     556                 * and needed modules.
     557                 */
     558                if ((ERROR_OCCURRED(char_map_add(&net_globals.netif_names,
     559                    netif->name, 0, index))) || (ERROR_OCCURRED(start_device(netif)))) {
     560                        measured_strings_destroy(&netif->configuration);
     561                        netifs_exclude_index(&net_globals.netifs, index);
     562                        return ERROR_CODE;
     563                }
     564               
     565                /* Increment modules' usage */
     566                netif->driver->usage++;
     567                if (netif->nil)
     568                        netif->nil->usage++;
     569                netif->il->usage++;
     570               
     571                printf("%s: Network interface started (name: %s, id: %d, driver: %s, "
     572                    "nil: %s, il: %s)\n", NAME, netif->name, netif->id,
     573                    netif->driver->name,  netif->nil ? netif->nil->name : "[none]",
     574                    netif->il->name);
     575        }
     576       
     577        return EOK;
     578}
     579
     580/** Process the networking message.
     581 *
     582 * @param[in] callid        The message identifier.
     583 * @param[in] call          The message parameters.
     584 * @param[out] answer       The message answer parameters.
     585 * @param[out] answer_count The last parameter for the actual answer
     586 *                          in the answer parameter.
     587 *
     588 * @returns EOK on success.
     589 * @returns ENOTSUP if the message is not known.
     590 *
     591 * @see net_interface.h
     592 * @see IS_NET_NET_MESSAGE()
     593 *
     594 */
     595int net_message(ipc_callid_t callid, ipc_call_t *call, ipc_call_t *answer,
     596    int *answer_count)
     597{
     598        ERROR_DECLARE;
     599       
    274600        measured_string_ref strings;
    275         char * data;
    276 
     601        char *data;
     602       
    277603        *answer_count = 0;
    278         switch(IPC_GET_METHOD(*call)){
     604        switch (IPC_GET_METHOD(*call)) {
    279605                case IPC_M_PHONE_HUNGUP:
    280606                        return EOK;
    281607                case NET_NET_GET_DEVICE_CONF:
    282                         ERROR_PROPAGATE(measured_strings_receive(&strings, &data, IPC_GET_COUNT(call)));
    283                         net_get_device_conf_req(0, IPC_GET_DEVICE(call), &strings, IPC_GET_COUNT(call), NULL);
    284                         // strings should not contain received data anymore
     608                        ERROR_PROPAGATE(measured_strings_receive(&strings, &data,
     609                            IPC_GET_COUNT(call)));
     610                        net_get_device_conf_req(0, IPC_GET_DEVICE(call), &strings,
     611                            IPC_GET_COUNT(call), NULL);
     612                       
     613                        /* Strings should not contain received data anymore */
    285614                        free(data);
     615                       
    286616                        ERROR_CODE = measured_strings_reply(strings, IPC_GET_COUNT(call));
    287617                        free(strings);
    288618                        return ERROR_CODE;
    289619                case NET_NET_GET_CONF:
    290                         ERROR_PROPAGATE(measured_strings_receive(&strings, &data, IPC_GET_COUNT(call)));
     620                        ERROR_PROPAGATE(measured_strings_receive(&strings, &data,
     621                            IPC_GET_COUNT(call)));
    291622                        net_get_conf_req(0, &strings, IPC_GET_COUNT(call), NULL);
    292                         // strings should not contain received data anymore
     623                       
     624                        /* Strings should not contain received data anymore */
    293625                        free(data);
     626                       
    294627                        ERROR_CODE = measured_strings_reply(strings, IPC_GET_COUNT(call));
    295628                        free(strings);
     
    301634}
    302635
    303 int parse_line(measured_strings_ref configuration, char * line){
    304         ERROR_DECLARE;
    305 
    306         measured_string_ref setting;
    307         char * name;
    308         char * value;
    309 
    310         // from the beginning
    311         name = line;
    312 
    313         // skip comments and blank lines
    314         if((*name == '#') || (*name == '\0')){
    315                 return EOK;
    316         }
    317         // skip spaces
    318         while(isspace(*name)){
    319                 ++ name;
    320         }
    321 
    322         // remember the name start
    323         value = name;
    324         // skip the name
    325         while(isalnum(*value) || (*value == '_')){
    326                 // make uppercase
    327 //              *value = toupper(*value);
    328                 ++ value;
    329         }
    330 
    331         if(*value == '='){
    332                 // terminate the name
    333                 *value = '\0';
    334         }else{
    335                 // terminate the name
    336                 *value = '\0';
    337                 // skip until '='
    338                 ++ value;
    339                 while((*value) && (*value != '=')){
    340                         ++ value;
    341                 }
    342                 // not found?
    343                 if(*value != '='){
    344                         return EINVAL;
    345                 }
    346         }
    347 
    348         ++ value;
    349         // skip spaces
    350         while(isspace(*value)){
    351                 ++ value;
    352         }
    353         // create a bulk measured string till the end
    354         setting = measured_string_create_bulk(value, 0);
    355         if(! setting){
    356                 return ENOMEM;
    357         }
    358 
    359         // add the configuration setting
    360         if(ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))){
    361                 free(setting);
    362                 return ERROR_CODE;
    363         }
    364         return EOK;
    365 }
    366 
    367 int read_configuration(void){
    368         // read the general configuration file
    369         return read_configuration_file(CONF_DIR, CONF_GENERAL_FILE, &net_globals.configuration);
    370 }
    371 
    372 int read_configuration_file(const char * directory, const char * filename, measured_strings_ref configuration){
    373         ERROR_DECLARE;
    374 
    375         size_t index = 0;
    376         char line[BUFFER_SIZE];
    377         FILE * cfg;
    378         int read;
    379         int line_number = 0;
    380 
    381         // construct the full filename
    382         printf("Reading file %s/%s\n", directory, filename);
    383         if(snprintf(line, BUFFER_SIZE, "%s/%s", directory, filename) > BUFFER_SIZE){
    384                 return EOVERFLOW;
    385         }
    386         // open the file
    387         cfg = fopen(line, "r");
    388         if(! cfg){
    389                 return ENOENT;
    390         }
    391 
    392         // read the configuration line by line
    393         // until an error or the end of file
    394         while((! ferror(cfg)) && (! feof(cfg))){
    395                 read = fgetc(cfg);
    396                 if((read > 0) && (read != '\n') && (read != '\r')){
    397                         if(index >= BUFFER_SIZE){
    398                                 line[BUFFER_SIZE - 1] = '\0';
    399                                 printf("line %d too long: %s\n", line_number, line);
    400                                 // no space left in the line buffer
    401                                 return EOVERFLOW;
    402                         }else{
    403                                 // append the character
    404                                 line[index] = (char) read;
    405                                 ++ index;
    406                         }
    407                 }else{
    408                         // on error or new line
    409                         line[index] = '\0';
    410                         ++ line_number;
    411                         if(ERROR_OCCURRED(parse_line(configuration, line))){
    412                                 printf("error on line %d: %s\n", line_number, line);
    413                                 //fclose(cfg);
    414                                 //return ERROR_CODE;
    415                         }
    416                         index = 0;
    417                 }
    418         }
    419         fclose(cfg);
    420         return EOK;
    421 }
    422 
    423 int read_netif_configuration(const char * name, netif_ref netif){
    424         // read the netif configuration file
    425         return read_configuration_file(CONF_DIR, name, &netif->configuration);
    426 }
    427 
    428 int start_device(netif_ref netif){
    429         ERROR_DECLARE;
    430 
    431         measured_string_ref setting;
    432         services_t internet_service;
    433         int irq;
    434         int io;
    435         int mtu;
    436 
    437         // mandatory netif
    438         setting = measured_strings_find(&netif->configuration, CONF_NETIF, 0);
    439         netif->driver = get_running_module(&net_globals.modules, setting->value);
    440         if(! netif->driver){
    441                 printf("Failed to start the network interface driver %s\n", setting->value);
    442                 return EINVAL;
    443         }
    444 
    445         // optional network interface layer
    446         setting = measured_strings_find(&netif->configuration, CONF_NIL, 0);
    447         if(setting){
    448                 netif->nil = get_running_module(&net_globals.modules, setting->value);
    449                 if(! netif->nil){
    450                         printf("Failed to start the network interface layer %s\n", setting->value);
    451                         return EINVAL;
    452                 }
    453         }else{
    454                 netif->nil = NULL;
    455         }
    456 
    457         // mandatory internet layer
    458         setting = measured_strings_find(&netif->configuration, CONF_IL, 0);
    459         netif->il = get_running_module(&net_globals.modules, setting->value);
    460         if(! netif->il){
    461                 printf("Failed to start the internet layer %s\n", setting->value);
    462                 return EINVAL;
    463         }
    464 
    465         // hardware configuration
    466         setting = measured_strings_find(&netif->configuration, CONF_IRQ, 0);
    467         irq = setting ? strtol(setting->value, NULL, 10) : 0;
    468         setting = measured_strings_find(&netif->configuration, CONF_IO, 0);
    469         io = setting ? strtol(setting->value, NULL, 16) : 0;
    470         ERROR_PROPAGATE(netif_probe_req(netif->driver->phone, netif->id, irq, io));
    471 
    472         // network interface layer startup
    473         if(netif->nil){
    474                 setting = measured_strings_find(&netif->configuration, CONF_MTU, 0);
    475                 if(! setting){
    476                         setting = measured_strings_find(&net_globals.configuration, CONF_MTU, 0);
    477                 }
    478                 mtu = setting ? strtol(setting->value, NULL, 10) : 0;
    479                 ERROR_PROPAGATE(nil_device_req(netif->nil->phone, netif->id, mtu, netif->driver->service));
    480                 internet_service = netif->nil->service;
    481         }else{
    482                 internet_service = netif->driver->service;
    483         }
    484 
    485         // inter-network layer startup
    486         switch(netif->il->service){
    487                 case SERVICE_IP:
    488                         ERROR_PROPAGATE(ip_device_req(netif->il->phone, netif->id, internet_service));
    489                         break;
    490                 default:
    491                         return ENOENT;
    492         }
    493         ERROR_PROPAGATE(netif_start_req(netif->driver->phone, netif->id));
    494         return EOK;
    495 }
    496 
    497 int startup(void){
    498         ERROR_DECLARE;
    499 
    500         const char * conf_files[] = {"lo", "ne2k"};
    501 
    502         int count = sizeof(conf_files) / sizeof(char *);
    503         int index;
    504         netif_ref netif;
    505         int i;
    506         measured_string_ref setting;
    507 
    508         for(i = 0; i < count; ++ i){
    509                 netif = (netif_ref) malloc(sizeof(netif_t));
    510                 if(! netif){
    511                         return ENOMEM;
    512                 }
    513 
    514                 netif->id = generate_new_device_id();
    515                 if(! netif->id){
    516                         return EXDEV;
    517                 }
    518                 ERROR_PROPAGATE(measured_strings_initialize(&netif->configuration));
    519 
    520                 // read configuration files
    521                 if(ERROR_OCCURRED(read_netif_configuration(conf_files[i], netif))){
    522                         measured_strings_destroy(&netif->configuration);
    523                         free(netif);
    524                         return ERROR_CODE;
    525                 }
    526 
    527                 // mandatory name
    528                 setting = measured_strings_find(&netif->configuration, CONF_NAME, 0);
    529                 if(! setting){
    530                         printf("The name is missing\n");
    531                         measured_strings_destroy(&netif->configuration);
    532                         free(netif);
    533                         return EINVAL;
    534                 }
    535                 netif->name = setting->value;
    536 
    537                 // add to the netifs map
    538                 index = netifs_add(&net_globals.netifs, netif->id, netif);
    539                 if(index < 0){
    540                         measured_strings_destroy(&netif->configuration);
    541                         free(netif);
    542                         return index;
    543                 }
    544 
    545                 // add to the netif names map
    546                 if(ERROR_OCCURRED(char_map_add(&net_globals.netif_names, netif->name, 0, index))
    547                 // start network interfaces and needed modules
    548                         || ERROR_OCCURRED(start_device(netif))){
    549                         measured_strings_destroy(&netif->configuration);
    550                         netifs_exclude_index(&net_globals.netifs, index);
    551                         return ERROR_CODE;
    552                 }
    553 
    554                 // increment modules' usage
    555                 ++ netif->driver->usage;
    556                 if(netif->nil){
    557                         ++ netif->nil->usage;
    558                 }
    559                 ++ netif->il->usage;
    560                 printf("New network interface started:\n\tname\t= %s\n\tid\t= %d\n\tdriver\t= %s\n\tnil\t= %s\n\til\t= %s\n", netif->name, netif->id, netif->driver->name, netif->nil ? netif->nil->name : NULL, netif->il->name);
    561         }
    562         return EOK;
    563 }
    564 
    565636/** Default thread for new connections.
    566637 *
    567  *  @param[in] iid The initial message identifier.
    568  *  @param[in] icall The initial message call structure.
    569  *
    570  */
    571 static void net_client_connection(ipc_callid_t iid, ipc_call_t * icall)
     638 * @param[in] iid The initial message identifier.
     639 * @param[in] icall The initial message call structure.
     640 *
     641 */
     642static void net_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    572643{
    573644        /*
     
    577648        ipc_answer_0(iid, EOK);
    578649       
    579         while(true) {
     650        while (true) {
     651                /* Clear the answer structure */
    580652                ipc_call_t answer;
    581653                int answer_count;
    582                
    583                 /* Clear the answer structure */
    584654                refresh_answer(&answer, &answer_count);
    585655               
     
    600670}
    601671
    602 /** Starts the module.
    603  *
    604  *  @param argc The count of the command line arguments. Ignored parameter.
    605  *  @param argv The command line parameters. Ignored parameter.
    606  *
    607  *  @returns EOK on success.
    608  *  @returns Other error codes as defined for each specific module start function.
    609  *
    610  */
    611672int main(int argc, char *argv[])
    612673{
    613674        ERROR_DECLARE;
    614675       
    615         /* Print the module label */
    616         printf("Task %d - %s\n", task_get_id(), NAME);
    617        
    618         /* Start the module */
    619676        if (ERROR_OCCURRED(net_module_start(net_client_connection))) {
    620                 printf(" - ERROR %i\n", ERROR_CODE);
     677                fprintf(stderr, "%s: net_module_start error %i\n", NAME, ERROR_CODE);
    621678                return ERROR_CODE;
    622679        }
Note: See TracChangeset for help on using the changeset viewer.