OpenCores
URL https://opencores.org/ocsvn/fpga-cf/fpga-cf/trunk

Subversion Repositories fpga-cf

[/] [fpga-cf/] [trunk/] [cpp/] [fcpprotocol.cpp] - Blame information for rev 11

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 10 peteralieb
// fcpprotocol.cpp
2
 
3
#include "fcpprotocol.hpp"
4
#include "rawethernet.hpp"
5
 
6
#include <iostream>
7
#include <cstring>
8
#include <arpa/inet.h>
9
 
10
using namespace std;
11
 
12
FCPProtocol::FCPProtocol()
13
{
14
        this->snd_cur = 0;
15
        this->last_ack = 0;
16
        this->enet = new RawEthernet();
17
}
18
 
19
FCPProtocol::~FCPProtocol()
20
{
21
        delete this->enet;
22
}
23
 
24
bool FCPProtocol::connect(byte mac[], byte ip[])
25
{
26
        if (!this->enet->connect(mac)) return false;
27
        memcpy((void*)this->ip, (void*)ip, 4);
28
        // send connection request
29
        memcpy((void*)this->buffer, (void*)this->packet_con, 34);
30
        memcpy((void*)(this->buffer+16), (void*)ip, 4);
31
        if (!this->enet->sendData(this->buffer, 34)) return false;
32
        // receive conack
33
        if (!this->receiveFcpUdpIp(1500, this->buffer)) return false;
34
        if (this->buffer[28] != (byte)0x1) return false;
35
        memcpy((void*)(this->sendbuf+16), (void*)this->ip, 4);
36
        this->snd_cur = 1;
37
        this->last_ack = 0;
38
        return true;
39
}
40
 
41
void FCPProtocol::disconnect()
42
{
43
        this->enet->disconnect();
44
        this->snd_cur = 0;
45
        this->last_ack = 0;
46
}
47
 
48
bool FCPProtocol::sendData(int channel, byte data[], int len)
49
{
50
        // wrap in packet
51
        this->wrapFcpUdpIp(FCP_DATA_SND, channel, data, len);
52
        // send packet
53
        if (!this->enet->sendData(this->buffer, len+34)) return false;
54
        // receive ack
55
        if (!this->receiveFcpUdpIp(1500, this->buffer)) return false;
56
        int seq = (int) ntohs(*((short*)&this->buffer[30]));
57
        if ((seq != this->snd_cur) || (this->buffer[28] != 1)) return false;
58
        this->last_ack = seq;
59
        this->snd_cur = seq+1;
60
        //this->snd_cur++;
61
        return true;
62
}
63
 
64
bool FCPProtocol::requestData(int channel, int len, byte *data)
65
{
66
        // send data request
67
        wrapFcpUdpIp(FCP_DATA_REQ, channel, NULL, len);
68
        if (!this->enet->sendData(this->buffer, 34)) return false;
69
        // receive data response
70
        if (!this->receiveFcpUdpIp(1500, this->buffer)) return false;
71
        int seq = (int) ntohs(*((short*)&this->buffer[30]));
72
        if ((seq != this->snd_cur) || (this->buffer[28] != 5)) return false;
73
        this->last_ack = seq;
74
        this->snd_cur = seq+1;
75
        memcpy((void*)data, (void*)(&this->buffer[34]), len);
76
        return true;
77
}
78
 
79
bool FCPProtocol::connected()
80
{
81
        return (this->snd_cur > 0);
82
}
83
 
84
void FCPProtocol::wrapFcpUdpIp(byte command, int channel, byte *data, int len)
85
{
86
        memcpy((void*)(this->buffer), (void*)this->ip_header, 20);
87
        memcpy((void*)(this->buffer+16), (void*)ip, 4);
88
        *((short*)&buffer[2]) = htons(34+len);
89
        //*** insert IP header checksum
90
        memcpy((void*)(this->buffer+20), (void*)this->udp_header, 8);
91
        *((short*)&buffer[24]) = htons(len+14);
92
        buffer[26] = 0;
93
        buffer[27] = 0;
94
        buffer[28] = command;
95
        buffer[29] = (byte)channel;
96
        *((short*)&(this->buffer[30])) = htons(this->snd_cur);
97
        *((short*)&(this->buffer[32])) = htons(len);
98
        if (len > 0 && data != NULL)
99
                memcpy((void*)(this->buffer+34), (void*)data, len);
100
        this->insertIPChecksum();
101
}
102
 
103
void FCPProtocol::insertIPChecksum()
104
{
105
        int sum = 0;
106
        short* buf = (short*)this->buffer;
107
        for (int i=0; i<20; i++)
108
        {
109
                sum += (int) ntohs(buf[i]);
110
                if (sum > 0xffff)
111
                {
112
                        sum = (sum & 0xffff) + 1;
113
                }
114
        }
115
        buf[5] = ~htons((short)sum&0xffff);
116
}
117
 
118
bool FCPProtocol::receiveFcpUdpIp(int len, byte *data)
119
{
120
        for (int i=0; i<20; i++)
121
        {
122
                if (!this->enet->requestData(len, data)) return false;
123
                if (data[9] != 0x11) continue;
124
                if (ntohs(*((short*)(data+20))) != 0x3001) continue;
125
                if (ntohs(*((short*)(data+22))) != 0x3000) continue;
126
                return true;
127
        }
128
        return false;
129
}
130
 
131
const byte FCPProtocol::packet_con[] = {//0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
132
                                                                0x45, 0, 0, 34/*len*/, 0, 0, 0, 0, 0x80, 0x11, 0, 0, 0xc0, 0xa8, 1, 0x66, 0, 0, 0, 0,
133
                                                                0x30, 0, 0x30, 1, 0, 0x0e, 0, 0,
134
                                                                0x02, 0, 0, 0, 0, 0};// len=34
135
const byte FCPProtocol::ip_header[] = {0x45, 0, 0, 34, 0, 0, 0, 0, 0x80, 0x11, 0, 0, 0xc0, 0xa8, 1, 0x66, 0, 0, 0, 0};// len=20
136
const byte FCPProtocol::udp_header[] = {0x30, 0, 0x30, 1, 0, 0x06, 0, 0};// len=8

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.