Changeset 89c57b6 in mainline for uspace/srv/net/netif/lo/lo.c
- Timestamp:
- 2011-04-13T14:45:41Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 88634420
- Parents:
- cefb126 (diff), 17279ead (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/netif/lo/lo.c
rcefb126 r89c57b6 28 28 29 29 /** @addtogroup lo 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 34 * Loopback network interface implementation. 35 35 */ 36 36 … … 39 39 #include <stdio.h> 40 40 #include <str.h> 41 42 #include <ipc/ipc.h>43 41 #include <ipc/services.h> 44 45 #include <net_err.h> 46 #include <net_messages.h> 47 #include <net_modules.h> 42 #include <ipc/nil.h> 43 #include <net/modules.h> 48 44 #include <adt/measured_strings.h> 49 #include <packet/packet_client.h> 50 #include <net_device.h> 51 #include <nil_interface.h> 52 #include <nil_messages.h> 53 #include <netif_interface.h> 54 #include <netif_local.h> 55 56 /** Default hardware address. 57 */ 58 #define DEFAULT_ADDR "\0\0\0\0\0\0" 59 60 /** Default address length. 61 */ 62 #define DEFAULT_ADDR_LEN (sizeof(DEFAULT_ADDR) / sizeof(char)) 63 64 /** Loopback module name. 65 */ 45 #include <packet_client.h> 46 #include <net/device.h> 47 #include <netif_skel.h> 48 #include <nil_remote.h> 49 50 /** Default address length. */ 51 #define DEFAULT_ADDR_LEN 6 52 53 /** Loopback module name. */ 66 54 #define NAME "lo" 67 55 68 /** Network interface global data. 69 */ 70 netif_globals_t netif_globals; 71 72 /** Changes the loopback state. 73 * @param[in] device The device structure. 74 * @param[in] state The new device state. 75 * @returns The new state if changed. 76 * @returns EOK otherwise. 77 */ 78 int change_state_message(netif_device_t * device, device_state_t state); 79 80 /** Creates and returns the loopback network interface structure. 81 * @param[in] device_id The new devce identifier. 82 * @param[out] device The device structure. 83 * @returns EOK on success. 84 * @returns EXDEV if one loopback network interface already exists. 85 * @returns ENOMEM if there is not enough memory left. 86 */ 87 int create(device_id_t device_id, netif_device_t * * device); 88 89 int netif_specific_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 56 static uint8_t default_addr[DEFAULT_ADDR_LEN] = 57 {0, 0, 0, 0, 0, 0}; 58 59 int netif_specific_message(ipc_callid_t callid, ipc_call_t *call, 60 ipc_call_t *answer, size_t *count) 61 { 90 62 return ENOTSUP; 91 63 } 92 64 93 int netif_get_addr_message(device_id_t device_id, measured_string_ref address){ 94 if(! address){ 65 int netif_get_addr_message(device_id_t device_id, measured_string_t *address) 66 { 67 if (!address) 95 68 return EBADMEM; 96 }97 address->value = str_dup(DEFAULT_ADDR);69 70 address->value = default_addr; 98 71 address->length = DEFAULT_ADDR_LEN; 99 return EOK; 100 } 101 102 int netif_get_device_stats(device_id_t device_id, device_stats_ref stats){ 103 ERROR_DECLARE; 104 105 netif_device_t * device; 106 107 if(! stats){ 72 73 return EOK; 74 } 75 76 int netif_get_device_stats(device_id_t device_id, device_stats_t *stats) 77 { 78 if (!stats) 108 79 return EBADMEM; 109 } 110 ERROR_PROPAGATE(find_device(device_id, &device)); 111 memcpy(stats, (device_stats_ref) device->specific, sizeof(device_stats_t)); 112 return EOK; 113 } 114 115 int change_state_message(netif_device_t * device, device_state_t state) 80 81 netif_device_t *device; 82 int rc = find_device(device_id, &device); 83 if (rc != EOK) 84 return rc; 85 86 memcpy(stats, (device_stats_t *) device->specific, 87 sizeof(device_stats_t)); 88 89 return EOK; 90 } 91 92 /** Change the loopback state. 93 * 94 * @param[in] device The device structure. 95 * @param[in] state The new device state. 96 * 97 * @return New state if changed. 98 * @return EOK otherwise. 99 * 100 */ 101 static void change_state_message(netif_device_t *device, device_state_t state) 116 102 { 117 103 if (device->state != state) { 118 104 device->state = state; 119 105 120 printf("%s: State changed to %s\n", NAME, 121 (state == NETIF_ACTIVE) ? "active" : "stopped"); 106 const char *desc; 107 switch (state) { 108 case NETIF_ACTIVE: 109 desc = "active"; 110 break; 111 case NETIF_STOPPED: 112 desc = "stopped"; 113 break; 114 default: 115 desc = "unknown"; 116 } 122 117 123 return state; 124 } 125 126 return EOK; 127 } 128 129 int create(device_id_t device_id, netif_device_t * * device){ 130 int index; 131 132 if(netif_device_map_count(&netif_globals.device_map) > 0){ 118 printf("%s: State changed to %s\n", NAME, desc); 119 } 120 } 121 122 /** Create and return the loopback network interface structure. 123 * 124 * @param[in] device_id New devce identifier. 125 * @param[out] device Device structure. 126 * 127 * @return EOK on success. 128 * @return EXDEV if one loopback network interface already exists. 129 * @return ENOMEM if there is not enough memory left. 130 * 131 */ 132 static int lo_create(device_id_t device_id, netif_device_t **device) 133 { 134 if (netif_device_map_count(&netif_globals.device_map) > 0) 133 135 return EXDEV; 134 }else{ 135 *device = (netif_device_t *) malloc(sizeof(netif_device_t)); 136 if(!(*device)){ 137 return ENOMEM; 138 } 139 (** device).specific = malloc(sizeof(device_stats_t)); 140 if(! (** device).specific){ 141 free(*device); 142 return ENOMEM; 143 } 144 null_device_stats((device_stats_ref)(** device).specific); 145 (** device).device_id = device_id; 146 (** device).nil_phone = -1; 147 (** device).state = NETIF_STOPPED; 148 index = netif_device_map_add(&netif_globals.device_map, (** device).device_id, * device); 149 if(index < 0){ 150 free(*device); 151 free((** device).specific); 152 *device = NULL; 153 return index; 154 } 155 } 156 return EOK; 157 } 158 159 int netif_initialize(void){ 160 ipcarg_t phonehash; 161 162 return REGISTER_ME(SERVICE_LO, &phonehash); 163 } 164 165 int netif_probe_message(device_id_t device_id, int irq, uintptr_t io){ 166 ERROR_DECLARE; 167 168 netif_device_t * device; 169 170 // create a new device 171 ERROR_PROPAGATE(create(device_id, &device)); 172 // print the settings 136 137 *device = (netif_device_t *) malloc(sizeof(netif_device_t)); 138 if (!*device) 139 return ENOMEM; 140 141 (*device)->specific = (device_stats_t *) malloc(sizeof(device_stats_t)); 142 if (!(*device)->specific) { 143 free(*device); 144 return ENOMEM; 145 } 146 147 null_device_stats((device_stats_t *) (*device)->specific); 148 (*device)->device_id = device_id; 149 (*device)->nil_phone = -1; 150 (*device)->state = NETIF_STOPPED; 151 int index = netif_device_map_add(&netif_globals.device_map, 152 (*device)->device_id, *device); 153 154 if (index < 0) { 155 free(*device); 156 free((*device)->specific); 157 *device = NULL; 158 return index; 159 } 160 161 return EOK; 162 } 163 164 int netif_initialize(void) 165 { 166 return async_connect_to_me(PHONE_NS, SERVICE_LO, 0, 0, NULL); 167 } 168 169 int netif_probe_message(device_id_t device_id, int irq, void *io) 170 { 171 /* Create a new device */ 172 netif_device_t *device; 173 int rc = lo_create(device_id, &device); 174 if (rc != EOK) 175 return rc; 176 173 177 printf("%s: Device created (id: %d)\n", NAME, device->device_id); 174 178 return EOK; 175 179 } 176 180 177 int netif_send_message(device_id_t device_id, packet_t packet, services_t sender){ 178 ERROR_DECLARE; 179 180 netif_device_t * device; 181 size_t length; 182 packet_t next; 183 int phone; 184 185 ERROR_PROPAGATE(find_device(device_id, &device)); 186 if(device->state != NETIF_ACTIVE){ 181 int netif_send_message(device_id_t device_id, packet_t *packet, services_t sender) 182 { 183 netif_device_t *device; 184 int rc = find_device(device_id, &device); 185 if (rc != EOK) 186 return EOK; 187 188 if (device->state != NETIF_ACTIVE) { 187 189 netif_pq_release(packet_get_id(packet)); 188 190 return EFORWARD; 189 191 } 190 next = packet; 191 do{ 192 ++ ((device_stats_ref) device->specific)->send_packets; 193 ++ ((device_stats_ref) device->specific)->receive_packets; 194 length = packet_get_data_length(next); 195 ((device_stats_ref) device->specific)->send_bytes += length; 196 ((device_stats_ref) device->specific)->receive_bytes += length; 192 193 packet_t *next = packet; 194 do { 195 ((device_stats_t *) device->specific)->send_packets++; 196 ((device_stats_t *) device->specific)->receive_packets++; 197 size_t length = packet_get_data_length(next); 198 ((device_stats_t *) device->specific)->send_bytes += length; 199 ((device_stats_t *) device->specific)->receive_bytes += length; 197 200 next = pq_next(next); 198 }while(next); 199 phone = device->nil_phone; 201 } while (next); 202 203 int phone = device->nil_phone; 200 204 fibril_rwlock_write_unlock(&netif_globals.lock); 205 201 206 nil_received_msg(phone, device_id, packet, sender); 207 202 208 fibril_rwlock_write_lock(&netif_globals.lock); 203 209 return EOK; 204 210 } 205 211 206 int netif_start_message(netif_device_t * device){ 207 return change_state_message(device, NETIF_ACTIVE); 208 } 209 210 int netif_stop_message(netif_device_t * device){ 211 return change_state_message(device, NETIF_STOPPED); 212 } 213 214 /** Default thread for new connections. 215 * 216 * @param[in] iid The initial message identifier. 217 * @param[in] icall The initial message call structure. 218 * 219 */ 220 static void netif_client_connection(ipc_callid_t iid, ipc_call_t *icall) 221 { 222 /* 223 * Accept the connection 224 * - Answer the first IPC_M_CONNECT_ME_TO call. 225 */ 226 ipc_answer_0(iid, EOK); 227 228 while(true) { 229 ipc_call_t answer; 230 int answer_count; 231 232 /* Clear the answer structure */ 233 refresh_answer(&answer, &answer_count); 234 235 /* Fetch the next message */ 236 ipc_call_t call; 237 ipc_callid_t callid = async_get_call(&call); 238 239 /* Process the message */ 240 int res = netif_module_message(NAME, callid, &call, &answer, 241 &answer_count); 242 243 /* End if said to either by the message or the processing result */ 244 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP)) 245 return; 246 247 /* Answer the message */ 248 answer_call(callid, res, &answer, answer_count); 249 } 212 int netif_start_message(netif_device_t *device) 213 { 214 change_state_message(device, NETIF_ACTIVE); 215 return device->state; 216 } 217 218 int netif_stop_message(netif_device_t *device) 219 { 220 change_state_message(device, NETIF_STOPPED); 221 return device->state; 250 222 } 251 223 252 224 int main(int argc, char *argv[]) 253 225 { 254 ERROR_DECLARE;255 256 226 /* Start the module */ 257 if (ERROR_OCCURRED(netif_module_start(netif_client_connection))) 258 return ERROR_CODE; 259 260 return EOK; 227 return netif_module_start(); 261 228 } 262 229
Note:
See TracChangeset
for help on using the changeset viewer.