summaryrefslogtreecommitdiff
path: root/i/marvin/src/proto/proto.hh
blob: 47ef9a0f79f80125547df5a0943d21d2cc22605c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#ifndef proto_hh
#define proto_hh
// proto.hh
// robert - programme du robot 2005. {{{
//
// Copyright (C) 2005 Nicolas Schodet
//
// Robot APB Team/Efrei 2005.
//        Web: http://assos.efrei.fr/robot/
//      Email: robot AT efrei DOT fr
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// }}}

#include "utils/non_copyable.hh"
#include "serial/serial.hh"
#include "log/log.hh"

#include <queue>
#include <stdint.h>

/// Classe de dialogue avec une carte �lectronique par le port s�rie.
class Proto : public NonCopyable
{
  public:
    class Receiver;
    /// Packet.
    struct Frame
    {
	char command;
	std::vector<uint8_t> args;
	bool operator==(const Frame& frame);
    };
  private:
    Log log_;
    Serial serial_;
    Receiver &receiver_;

    /// File d'attente des messages � aquiter.
    typedef std::queue<Frame> FrameQueue;
    FrameQueue frameQueue_;
    //Date du dernier envoie
    int tLastSend_; 
    //Temps entre les r�-�mission
    static const int timeout_ = 100;

    /// Frame en cours de r�ception
    Frame currentFrame_;
    int revState_;
    // Etat de la r�ception de la frame
    // 0 - Rien re�u
    // 1 - Bang re�u
    // 2 - Commande re�u & nouveau argument
    // 3 - char 1 argument re�u
    
  public:
    /// Constructeur.
    Proto (Receiver &receiver);
    /// Ouvre le port s�rie.
    void open (const std::string &ttyname);
    /// Ferme le port s�rie.
    void close (void);
    /// Teste si tout les packets ont �t� envoy�s et aquit�s, sinon, essaye de
    /// le faire.
    bool sync (void);
    /// Envois un packet.
    void send (const Frame &frame, bool reliable = true);
    /// Envois un packet. COMMAND est la commande � envoyer, FORMAT, donne le
    /// format et le nombre de param�tres ('b' : 8 bits, 'w' : 16 bits, 'd' :
    /// 32 bits, majuscule pour sign�).
    void send (char command, const char *format = "", int a0 = 0, int a1 = 0,
	       int a2 = 0, int a3 = 0, int a4 = 0, int a5 = 0, bool reliable = true);
    /// permet d'envoyer un packet robert
    void Proto::sendUnreliable (char command, const char *format, int a0,
				int a1, int a2, int a3, int a4, int a5);
    //@{
    /// Teste si le packet correspond au format et d�code les valeurs. Utilise
    /// le m�me format que send.
    static bool decode (const Frame &frame);
    static bool decode (const Frame &frame, const char *format, int &a0);
    static bool decode (const Frame &frame, const char *format, int &a0, int
			&a1);
    static bool decode (const Frame &frame, const char *format, int &a0, int
			&a1, int &a2);
    static bool decode (const Frame &frame, const char *format, int &a0, int
			&a1, int &a2, int &a3);
    //@}
    /// Attend que des caract�res soit disponible pendant un temps maximum en
    /// milliseconde et les traite. Renvois le r�sultat de sync (). Attention,
    /// fonction bloquante, n'utiliser que pour les tests.
    bool wait (int timeout = -1);
    /// R�cup�re le File Descriptor
    int getFd(void);

  public:
    /// Les clients de Proto doivent d�river de Receiver.
    class Receiver
      {
      public:
	virtual ~Receiver(void) {};
	/// Recoit un packet.
	virtual void receive (char command, const Frame &frame) = 0;
      };
  private:
    /// R�cup�re les infos de l'AVR pour construire une frame
    bool getFrame(void);
    /// Envoie la frame dans l'AVR
    void sendFrame(const Frame & frame);
    /// Remplie une frame avec un argument
    void newArgFrame(Proto::Frame & frame, char format, int arg);
    /// Renvoie la taille necessaire du vecteur args pour un format donn�
    static int  argsFrameSize(const char *format);
    /// D�code un argument
    static void decodeArg(const Frame & frame, const char *format, int &a0,
	    		  int &a1, int &a2, int &a3);
};

/// Affiche une frame.
std::ostream &
operator<< (std::ostream &os, const Proto::Frame &f);

#endif // proto_hh