]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi/src/dev.cpp
Se cambia el logueo de paquetes dropeados a std::cerr para diferenciar de
[z.facultad/75.74/practicos.git] / practicas / pipi / src / dev.cpp
1 #include "dev.h"
2 #include <cstring>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <sys/types.h>
6 #include <sys/ipc.h>
7 #include <sys/msg.h>
8 #ifdef DEBUG
9 #include <iostream>
10 #endif
11
12 struct Frame
13 {
14     Dev::mac_type mac;
15     size_t size;
16     char frame[1];
17 };
18
19 Dev::Dev(mac_type mac, size_t mtu, key_t key)
20     throw (std::runtime_error, std::logic_error):
21     mac(mac), mtu(mtu)
22 {
23     if (mtu > DEV_MAX_MTU)
24         throw std::logic_error("MTU más grande que DEV_MAX_MTU");
25     que_id = msgget(key, 0666); // Debe estar previamente creada
26     if (que_id == -1)
27         throw std::runtime_error("No se pudo crear la cola");
28 }
29
30 void Dev::transmit(const std::string& data, const mac_type& mac)
31     throw (std::runtime_error, std::logic_error)
32 {
33     if (data.size() > mtu)
34         throw std::logic_error("Tamaño de datos mayor al MTU");
35     Frame* f = (Frame*) malloc(sizeof(Frame) + mtu);
36     if (!f)
37         throw std::runtime_error("No se puede reservar memoria");
38     f->mac = mac;
39     f->size = data.size();
40     memcpy(f->frame, data.c_str(), data.size());
41     int res = msgsnd(que_id, f, mtu + sizeof(size_t), 0);
42 #ifdef DEBUG
43     std::cout << "Dev::transmit(msgtype/mac = " << f->mac << ", size = "
44         << f->size << ")\n";
45 #endif
46     free(f);
47     if (res == -1)
48         throw std::runtime_error("Error al poner en la cola");
49 }
50
51 std::string Dev::receive() throw (std::runtime_error)
52 {
53     Frame* f = (Frame*) malloc(sizeof(Frame) + mtu);
54     if (!f)
55         throw std::runtime_error("No se puede reservar memoria");
56     int res = msgrcv(que_id, f, mtu + sizeof(size_t), mac, 0);
57     if (res == -1)
58     {
59         free(f);
60         throw std::runtime_error("Error al sacar de la cola");
61     }
62     std::string s((char*) f->frame, f->size);
63     free(f);
64 #ifdef DEBUG
65     std::cout << "Dev::receive(msgtype/mac = " << mac << ", size = "
66         << s.size() << ")\n";
67 #endif
68     return s;
69 }
70
71 // vim: set et sw=4 sts=4 :