/*
EIBD eib bus access and management daemon
Copyright (C) 2005-2007 Martin Koegler <mkoegler@auto.tuwien.ac.at>
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 "eibusb.h"
#include "emi1.h"
#include "emi2.h"
LowLevelDriverInterface *
initUSBDriver (LowLevelDriverInterface * i, Trace * tr)
{
CArray r1, *r = 0;
LowLevelDriverInterface *iface;
uchar emiver;
const uchar ask[64] = {
0x01, 0x13, 0x09, 0x00, 0x08, 0x00, 0x01, 0x0f, 0x01, 0x00, 0x00, 0x01
};
uchar init[64] = {
0x01, 0x13, 0x0a, 0x00, 0x08, 0x00, 0x02, 0x0f, 0x03, 0x00, 0x00, 0x05,
0x01
};
i->Send_Packet (CArray (ask, sizeof (ask)));
do
{
r = i->Get_Packet (0);
if (r)
{
r1 = *r;
if (r1 () != 64)
goto cont;
if (r1[0] != 01)
goto cont;
if ((r1[1] & 0x0f) != 0x03)
goto cont;
if (r1[2] != 0x0b)
goto cont;
if (r1[3] != 0x00)
goto cont;
if (r1[4] != 0x08)
goto cont;
if (r1[5] != 0x00)
goto cont;
if (r1[6] != 0x03)
goto cont;
if (r1[7] != 0x0F)
goto cont;
if (r1[8] != 0x02)
goto cont;
if (r1[11] != 0x01)
goto cont;
break;
cont:
delete r;
r = 0;
}
}
while (!r);
delete r;
if (r1[13] & 0x2)
emiver = 2;
else if (r1[13] & 0x1)
emiver = 1;
else if (r1[13] & 0x4)
emiver = 3;
else
emiver = 0;
switch (emiver)
{
case 1:
init[12] = 1;
i->Send_Packet (CArray (init, sizeof (init)));
iface =
new USBConverterInterface (i, tr, LowLevelDriverInterface::vEMI1);
break;
case 2:
init[12] = 2;
i->Send_Packet (CArray (init, sizeof (init)));
iface =
new USBConverterInterface (i, tr, LowLevelDriverInterface::vEMI2);
break;
case 3:
init[12] = 3;
i->Send_Packet (CArray (init, sizeof (init)));
iface =
new USBConverterInterface (i, tr, LowLevelDriverInterface::vCEMI);
break;
default:
TRACEPRINTF (tr, 1, i, "Unsupported EMI %02x %02x", r1[12], r1[13]);
throw Exception (DEV_OPEN_FAIL);
break;
}
return iface;
}
USBConverterInterface::USBConverterInterface (LowLevelDriverInterface * iface,
Trace * tr, EMIVer ver)
{
t = tr;
i = iface;
v = ver;
switch (v)
{
case vEMI1:
TRACEPRINTF (t, 1, this, "EMI1");
break;
case vEMI2:
TRACEPRINTF (t, 1, this, "EMI2");
break;
case vCEMI:
TRACEPRINTF (t, 1, this, "CEMI");
break;
default:
TRACEPRINTF (t, 1, this, "Unknown EMI");
}
}
USBConverterInterface::~USBConverterInterface ()
{
delete i;
}
void
USBConverterInterface::Send_Packet (CArray l)
{
t->TracePacket (0, this, "Send-EMI", l);
CArray out;
int j, l1;
l1 = l ();
out.resize (64);
if (l1 + 11 > 64)
l1 = 64 - 11;
for (j = 0; j < out (); j++)
out[j] = 0;
for (j = 0; j < l1; j++)
out[j + 11] = l[j];
out[0] = 1;
out[1] = 0x13;
out[2] = l1 + 8;
out[3] = 0x0;
out[4] = 0x08;
out[5] = 0x00;
out[6] = l1;
out[7] = 0x01;
switch (v)
{
case vEMI1:
out[8] = 0x01;
break;
case vEMI2:
out[8] = 0x02;
break;
case vCEMI:
out[8] = 0x03;
break;
}
i->Send_Packet (out);
}
CArray *
USBConverterInterface::Get_Packet (pth_event_t stop)
{
CArray *res1 = i->Get_Packet (stop);
if (res1)
{
CArray res = *res1;
if (res () != 64)
goto out;
if (res[0] = !0x01)
goto out;
if ((res[1] & 0x0f) != 3)
goto out;
if (res[2] > 64 - 8)
goto out;
if (res[3] != 0)
goto out;
if (res[4] != 8)
goto out;
if (res[5] != 0)
goto out;
if (res[6] + 11 > 64)
goto out;
if (res[7] != 1)
goto out;
switch (v)
{
case vEMI1:
if (res[8] != 1)
goto out;
break;
case vEMI2:
if (res[8] != 2)
goto out;
break;
case vCEMI:
if (res[8] != 3)
goto out;
break;
default:
goto out;
}
res1->set (res.array () + 11, res[6]);
t->TracePacket (0, this, "RecvEMI", *res1);
}
return res1;
out:
delete res1;
return 0;
}
void
USBConverterInterface::SendReset ()
{
return i->SendReset ();
}
bool
USBConverterInterface::Connection_Lost ()
{
return i->Connection_Lost ();
}
LowLevelDriverInterface::EMIVer USBConverterInterface::getEMIVer ()
{
return v;
}
pth_sem_t *
USBConverterInterface::Send_Queue_Empty_Cond ()
{
return i->Send_Queue_Empty_Cond ();
}
bool
USBConverterInterface::Send_Queue_Empty ()
{
return i->Send_Queue_Empty ();
}
USBLayer2Interface::USBLayer2Interface (LowLevelDriverInterface * i,
Trace * tr)
{
emi = 0;
LowLevelDriverInterface *iface = initUSBDriver (i, tr);
switch (iface->getEMIVer ())
{
case LowLevelDriverInterface::vEMI1:
emi = new EMI1Layer2Interface (iface, tr);
break;
case LowLevelDriverInterface::vEMI2:
emi = new EMI2Layer2Interface (iface, tr);
break;
default:
TRACEPRINTF (tr, 2, this, "Unsupported EMI");
throw Exception (DEV_OPEN_FAIL);
}
}
USBLayer2Interface::~USBLayer2Interface ()
{
if (emi)
delete emi;
}
bool USBLayer2Interface::addAddress (eibaddr_t addr)
{
return emi->addAddress (addr);
}
bool USBLayer2Interface::addGroupAddress (eibaddr_t addr)
{
return emi->addGroupAddress (addr);
}
bool USBLayer2Interface::removeAddress (eibaddr_t addr)
{
return emi->removeAddress (addr);
}
bool USBLayer2Interface::removeGroupAddress (eibaddr_t addr)
{
return emi->removeGroupAddress (addr);
}
bool USBLayer2Interface::Connection_Lost ()
{
return emi->Connection_Lost ();
}
eibaddr_t USBLayer2Interface::getDefaultAddr ()
{
return emi->getDefaultAddr ();
}
bool USBLayer2Interface::openVBusmonitor ()
{
return emi->openVBusmonitor ();
}
bool USBLayer2Interface::closeVBusmonitor ()
{
return emi->closeVBusmonitor ();
}
bool USBLayer2Interface::enterBusmonitor ()
{
return emi->enterBusmonitor ();
}
bool USBLayer2Interface::leaveBusmonitor ()
{
return emi->leaveBusmonitor ();
}
bool USBLayer2Interface::Open ()
{
return emi->Open ();
}
bool USBLayer2Interface::Close ()
{
return emi->Close ();
}
bool USBLayer2Interface::Send_Queue_Empty ()
{
return emi->Send_Queue_Empty ();
}
void
USBLayer2Interface::Send_L_Data (LPDU * l)
{
emi->Send_L_Data (l);
}
LPDU *
USBLayer2Interface::Get_L_Data (pth_event_t stop)
{
return emi->Get_L_Data (stop);
}
syntax highlighted by Code2HTML, v. 0.9.1