]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi/src/dev.cpp
Se refactoriza y simplifica la capa física. Se deja sólo el dispositivo de red
[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) throw (std::runtime_error):
20     mac(mac), mtu(mtu)
21 {
22     que_id = msgget(key, 0666); // Debe estar previamente creada
23     if (que_id == -1)
24         throw std::runtime_error("No se pudo crear la cola");
25 }
26
27 void Dev::transmit(const std::string& data, const mac_type& mac)
28     throw (std::runtime_error, std::logic_error)
29 {
30     if (data.size() > mtu)
31         throw std::logic_error("Tamaño de datos mayor al MTU");
32     Frame* f = (Frame*) malloc(sizeof(Frame) + mtu);
33     if (!f)
34         throw std::runtime_error("No se puede reservar memoria");
35     f->mac = mac;
36     f->size = data.size();
37     memcpy(f->frame, data.c_str(), data.size());
38     int res = msgsnd(que_id, f, mtu + sizeof(size_t), 0);
39 #ifdef DEBUG
40     std::cout << "Dev::transmit(msgtype/mac = " << f->mac << ", size = "
41         << f->size << ", data = " << f->frame << ")\n";
42 #endif
43     free(f);
44     if (res == -1)
45         throw std::runtime_error("Error al poner en la cola");
46 }
47
48 std::string Dev::receive() throw (std::runtime_error)
49 {
50     Frame* f = (Frame*) malloc(sizeof(Frame) + mtu);
51     if (!f)
52         throw std::runtime_error("No se puede reservar memoria");
53     int res = msgrcv(que_id, f, mtu + sizeof(size_t), mac, 0);
54     if (res == -1)
55     {
56         free(f);
57         throw std::runtime_error("Error al sacar de la cola");
58     }
59     std::string s((char*) f->frame, f->size);
60     free(f);
61 #ifdef DEBUG
62     std::cout << "Dev::receive(msgtype/mac = " << mac << ", size = "
63         << s.size() << ", data = " << s << ")\n";
64 #endif
65     return s;
66 }
67
68 // vim: set et sw=4 sts=4 :