lo.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2009 Lukas Mejdrech
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00037 #include <async.h>
00038 #include <errno.h>
00039 #include <stdio.h>
00040 #include <str.h>
00041 #include <ipc/services.h>
00042 #include <ipc/nil.h>
00043 #include <net/modules.h>
00044 #include <adt/measured_strings.h>
00045 #include <packet_client.h>
00046 #include <net/device.h>
00047 #include <netif_skel.h>
00048 #include <nil_remote.h>
00049 
00051 #define DEFAULT_ADDR_LEN  6
00052 
00054 #define NAME  "lo"
00055 
00056 static uint8_t default_addr[DEFAULT_ADDR_LEN] =
00057     {0, 0, 0, 0, 0, 0};
00058 
00059 int netif_specific_message(ipc_callid_t callid, ipc_call_t *call,
00060     ipc_call_t *answer, size_t *count)
00061 {
00062         return ENOTSUP;
00063 }
00064 
00065 int netif_get_addr_message(device_id_t device_id, measured_string_t *address)
00066 {
00067         if (!address)
00068                 return EBADMEM;
00069         
00070         address->value = default_addr;
00071         address->length = DEFAULT_ADDR_LEN;
00072         
00073         return EOK;
00074 }
00075 
00076 int netif_get_device_stats(device_id_t device_id, device_stats_t *stats)
00077 {
00078         if (!stats)
00079                 return EBADMEM;
00080         
00081         netif_device_t *device;
00082         int rc = find_device(device_id, &device);
00083         if (rc != EOK)
00084                 return rc;
00085         
00086         memcpy(stats, (device_stats_t *) device->specific,
00087             sizeof(device_stats_t));
00088         
00089         return EOK;
00090 }
00091 
00101 static void change_state_message(netif_device_t *device, device_state_t state)
00102 {
00103         if (device->state != state) {
00104                 device->state = state;
00105                 
00106                 const char *desc;
00107                 switch (state) {
00108                 case NETIF_ACTIVE:
00109                         desc = "active";
00110                         break;
00111                 case NETIF_STOPPED:
00112                         desc = "stopped";
00113                         break;
00114                 default:
00115                         desc = "unknown";
00116                 }
00117                 
00118                 printf("%s: State changed to %s\n", NAME, desc);
00119         }
00120 }
00121 
00132 static int lo_create(device_id_t device_id, netif_device_t **device)
00133 {
00134         if (netif_device_map_count(&netif_globals.device_map) > 0)
00135                 return EXDEV;
00136         
00137         *device = (netif_device_t *) malloc(sizeof(netif_device_t));
00138         if (!*device)
00139                 return ENOMEM;
00140         
00141         (*device)->specific = (device_stats_t *) malloc(sizeof(device_stats_t));
00142         if (!(*device)->specific) {
00143                 free(*device);
00144                 return ENOMEM;
00145         }
00146         
00147         null_device_stats((device_stats_t *) (*device)->specific);
00148         (*device)->device_id = device_id;
00149         (*device)->nil_phone = -1;
00150         (*device)->state = NETIF_STOPPED;
00151         int index = netif_device_map_add(&netif_globals.device_map,
00152             (*device)->device_id, *device);
00153         
00154         if (index < 0) {
00155                 free(*device);
00156                 free((*device)->specific);
00157                 *device = NULL;
00158                 return index;
00159         }
00160         
00161         return EOK;
00162 }
00163 
00164 int netif_initialize(void)
00165 {
00166         return async_connect_to_me(PHONE_NS, SERVICE_LO, 0, 0, NULL);
00167 }
00168 
00169 int netif_probe_message(device_id_t device_id, int irq, void *io)
00170 {
00171         /* Create a new device */
00172         netif_device_t *device;
00173         int rc = lo_create(device_id, &device);
00174         if (rc != EOK)
00175                 return rc;
00176         
00177         printf("%s: Device created (id: %d)\n", NAME, device->device_id);
00178         return EOK;
00179 }
00180 
00181 int netif_send_message(device_id_t device_id, packet_t *packet, services_t sender)
00182 {
00183         netif_device_t *device;
00184         int rc = find_device(device_id, &device);
00185         if (rc != EOK)
00186                 return EOK;
00187         
00188         if (device->state != NETIF_ACTIVE) {
00189                 netif_pq_release(packet_get_id(packet));
00190                 return EFORWARD;
00191         }
00192         
00193         packet_t *next = packet;
00194         do {
00195                 ((device_stats_t *) device->specific)->send_packets++;
00196                 ((device_stats_t *) device->specific)->receive_packets++;
00197                 size_t length = packet_get_data_length(next);
00198                 ((device_stats_t *) device->specific)->send_bytes += length;
00199                 ((device_stats_t *) device->specific)->receive_bytes += length;
00200                 next = pq_next(next);
00201         } while (next);
00202         
00203         int phone = device->nil_phone;
00204         fibril_rwlock_write_unlock(&netif_globals.lock);
00205         
00206         nil_received_msg(phone, device_id, packet, sender);
00207         
00208         fibril_rwlock_write_lock(&netif_globals.lock);
00209         return EOK;
00210 }
00211 
00212 int netif_start_message(netif_device_t *device)
00213 {
00214         change_state_message(device, NETIF_ACTIVE);
00215         return device->state;
00216 }
00217 
00218 int netif_stop_message(netif_device_t *device)
00219 {
00220         change_state_message(device, NETIF_STOPPED);
00221         return device->state;
00222 }
00223 
00224 int main(int argc, char *argv[])
00225 {
00226         /* Start the module */
00227         return netif_module_start();
00228 }
00229 

Generated on Thu Jun 2 07:45:50 2011 for HelenOS/USB by  doxygen 1.4.7