00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
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
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
00227 return netif_module_start();
00228 }
00229