Hi I'm trying to program an extension to the S60_3rd_MR API to let me do infrared communication with an IrDA development board (MCP2150 if it matters). Using the C++ API I have managed to get the example code GlassTerm.cpp into such a shape that it allows me to send and receive characters to the board (that has a loopback connector Rx->TX and CTS/RTS are grounded).
I have wrapped python around some of the methods and altered some others to try to get this thing running and I can call the module and write a character to the port which results in my development board realising there is another device connected.
Using python (bluetooth console) I then try to read and always the receive an empty buffer, when the length of the buffer is queried or readoneormore is used then the interpreter crashes e.g. either of the lines below cause a crash.
numberRead = commPort.QueryReceiveBuffer();
commPort.ReadOneOrMore(readStat, localInputBuffer);
If anyone has anything that can help me do this, or has any experience of what can and can't be done with Python and IrDA please help, my code is below:
//PyS60serial
#include <e32std.h>
#include <EIKBTGPC.H>
#include <avkon.hrh>
#include <aknnavi.h>
#include <aknnavide.h>
#include <eikspane.h>
#include <aknappui.h>
#include <e32base.h>
#include <e32test.h>
#include <e32svr.h>
#include <e32keys.h>
#include <c32comm.h>
#include <f32file.h>
#include <Python.h>
#include <symbian_python_ext_util.h>
#include <e32cons.h>
// exclude console
// LOCAL_D CConsoleBase* console;
_LIT(LDD_NAME,"ECOMM");
#if defined (__WINS__)
_LIT(PDD_NAME,"ECDRV");
#else
_LIT(PDD_NAME,"EUART1");
#endif
// short literals for print debug when running as a C file only
_LIT(KMessage2,"%c\n");
_LIT(KMessage14,"^%c");
_LIT(KMessage15,"%c");
_LIT(KColons,"::");
_LIT(KMessage0,"Select S for RS232 Serial or R for InfraRed port : ");
_LIT(KMessage1,"Select 0 for no handshaking, 1 for CTS/RTS and 2 for XON/XOFF :");
_LIT(KMessage4,"Loading device drivers\n");
_LIT(KMessage5,"Starting comms server\n");
_LIT(KMessage6,"Connecting to comms server\n");
_LIT(KMessage7,"Loading %S.CSY module\n");
_LIT(KMessage8,"%S has %S available as %S::%u to %S::%u\n");
_LIT(KMessage9,"Opened %S\n");
_LIT(KMessage10,"Configuring Serial port for 115200 bps 8 bits no parity 1 stop\n");
_LIT(KMessage11,"Powering up port\n");
_LIT(KMessage12,"\nDisconnecting\n");
_LIT(KMessage13,"\nWrite Failed %d\n");
_LIT(KMessage16,"\nRead failed %d\n");
_LIT(KMessage17,"Closed %S\n");
_LIT(KMessage18,"Closing server connection\n");
_LIT(KMessage19,"Comms server reports we have %u comms modules loaded\n");
_LIT(KMessage20,"Using the lowest %S out of %S::%u to %S::%u\n");
_LIT(KMessage21,"Complete\n");
_LIT(KPanic,"StraySignal");
_LIT(RS232,"BTCOMM");
_LIT(IRCOMM,"IRCOMM");
// Define an arbitrary buffer size and Hundred seconds in microseconds
const TInt KBufSize (1);
const TInt KOneHundredSecond (100000000);
TInt r;
TKeyCode handshakingMode; // No handshaking
TBuf16 < 6 > csyName;
TUint8 csyMode='R'; // Use IRdA instead of BT or USB
const TUint8 mask=0xdf; // this mask 0xdf turns lower to upper case
RCommServ server;
RComm commPort;
TCommCaps ourCapabilities;
TCommConfig portSettings;
TKeyCode key;
TPtrC8 outputByte ((TUint8 *) & key, 1);
TBuf8 < KBufSize > localInputBuffer;
TRequestStatus readStat, keyStat;
const TTimeIntervalMicroSeconds32 KTenthSecond(3000000);
void printReceivedText(TDes8& localInputBuff,TInt numberRead)
{
TUint8 *nextByte = &localInputBuff[0];
for (int i = 0; i < numberRead; i++, nextByte++)
{
}
}
//serial
static PyObject* PyS60serial_IRsetup(PyObject* /*self*/, PyObject *args)
{
char* text_ = 0;
TInt textlen = 0;
if (!PyArg_ParseTuple(args, "u#", &text_, &textlen))
{
return 0;
}
TPtrC text((TUint16*)text_, textlen);
TRAPD(err,
CEikButtonGroupContainer::Current()->SetCommandL(EAknSoftkeyExit, text);
CEikButtonGroupContainer::Current()->DrawDeferred();
csyName.Copy(IRCOMM);
User::LeaveIfError(server.Connect());
r=server.LoadCommModule (csyName);
User::LeaveIfError(r);
TSerialInfo portInfo;
r=server.GetPortInfo(csyName,portInfo);
TBuf16 < KMaxPortName + 4 > portName;
portName.Num(portInfo.iLowUnit);
portName.Insert(0,KColons);
portName.Insert(0,portInfo.iName);
r=commPort.Open(server,portName,ECommExclusive);
commPort.Caps(ourCapabilities);
commPort.Config (portSettings);
portSettings ().iRate = EBps9600;
portSettings ().iParity = EParityNone;
portSettings ().iDataBits = EData8;
portSettings ().iStopBits = EStop1;
portSettings ().iFifo = EFifoEnable;
portSettings ().iHandshake = KConfigFailDSR; // for no handshaking
portSettings ().iTerminator[0] = 10;
portSettings ().iTerminatorCount = 1; // so that we terminate a read on each line feed arrives
r = commPort.SetConfig (portSettings);
User::LeaveIfError (r);
// now turn on DTR and RTS, and set our buffer size
commPort.SetSignals (KSignalDTR, 0);
commPort.SetSignals (KSignalRTS, 0);
TInt curlenth = commPort.ReceiveBufferLength ();
commPort.SetReceiveBufferLength (256);
curlenth = commPort.ReceiveBufferLength ();
// now we can start using the port
);
return Py_BuildValue("s", "HEllo");
//RETURN_ERROR_OR_PYNONE(err);
}
static PyObject* PyS60serial_initcon(PyObject* /*self*/, PyObject *args)
{
char* text_ = 0;
TInt textlen = 0;
if (!PyArg_ParseTuple(args, "u#", &text_, &textlen))
{
return 0;
}
TPtrC text((TUint16*)text_, textlen);
// Load drivers
TRAPD(err,
// a null read or write powers up the port
commPort.Read (readStat, localInputBuffer, 0);
User::WaitForRequest(readStat);
r = readStat.Int ();
User::LeaveIfError (r);
);
RETURN_ERROR_OR_PYNONE(err);
}
static PyObject* PyS60serial_r2(PyObject* /*self*/, PyObject *args)
{
int i=0;
char* text_ = 0;
char* rtxt[6];
char dtxt[6];
TInt textlen = 0;
if (!PyArg_ParseTuple(args, "u#", &text_, &textlen))
{
return 0;
}
TPtrC text((TUint16*)text_, textlen);
rtxt[0]="p";
rtxt[1]="p";
rtxt[2]="p";
rtxt[3]="p";
rtxt[4]="p";
dtxt[0]='n';
dtxt[1]='n';
dtxt[2]='n';
dtxt[3]='n';
dtxt[4]='n';
dtxt[5]='n';
// Load drivers
//TRAPD(err,
commPort.Read (readStat, KOneHundredSecond, localInputBuffer);
for (;
{
User::WaitForRequest (readStat);
dtxt[0]='y';
// From keyboard
if (readStat != KRequestPending)
{
dtxt[1]='y';
if (readStat == KErrNone || readStat == KErrTimedOut)
{
// check descriptor and print any characters
dtxt[2]='y';
TInt numberRead = localInputBuffer.Length ();
if (numberRead != 0)
{printReceivedText(localInputBuffer,numberRead);
dtxt[3]='y';}
else
// else check the input buffer and print any characters
{
dtxt[4]='y';
numberRead = commPort.QueryReceiveBuffer();
if (numberRead != 0)
{
dtxt[5]='y';
commPort.ReadOneOrMore(readStat, localInputBuffer);
User::WaitForRequest (readStat);
if (readStat == KErrNone) printReceivedText(localInputBuffer,numberRead);
}
}
}
else // An error occured on reading
commPort.Read (readStat, KOneHundredSecond, localInputBuffer);
}
// help !! a request we can't cater fo
}
//);
return Py_BuildValue("s#", dtxt,6);
}
static PyObject* PyS60serial_close(PyObject* /*self*/, PyObject *args)
{
char* text_ = 0;
TInt textlen = 0;
if (!PyArg_ParseTuple(args, "u#", &text_, &textlen))
{
return 0;
}
TPtrC text((TUint16*)text_, textlen);
TRAPD(err,
commPort.Close ();
server.Close ();
);
return Py_BuildValue("s", "close");
}
static PyObject* PyS60serial_write(PyObject* /*self*/, PyObject *args)
{
char* text_ = 0;
TInt textlen = 0;
if (!PyArg_ParseTuple(args, "u#", &text_, &textlen))
{
return 0;
}
TPtrC text((TUint16*)text_, textlen);
TRAPD(err,
key = (TKeyCode) 0x61;
TRequestStatus stat;
commPort.Write (stat, outputByte);
User::WaitForRequest (stat);
r = stat.Int ();
if (r != KErrNone) // Write has failed for some reason
);
return Py_BuildValue("s", "write");
}
static PyObject* PyS60serial_cr(PyObject* /*self*/, PyObject *args)
{
char* text_ = 0;
TInt textlen = 0;
if (!PyArg_ParseTuple(args, "u#", &text_, &textlen))
{
return 0;
}
TPtrC text((TUint16*)text_, textlen);
TRAPD(err,
key = (TKeyCode)0x0d;
TRequestStatus stat;
commPort.Write (stat, outputByte);
User::WaitForRequest (stat);
r = stat.Int ();
if (r != KErrNone) // Write has failed for some reason
);
return Py_BuildValue("s", "carriage return");
}
static const PyMethodDef PyS60serial_methods[] =
{
{"init", (PyCFunction)PyS60serial_IRsetup, METH_VARARGS},
{"con", (PyCFunction)PyS60serial_initcon, METH_VARARGS},
{"r2", (PyCFunction)PyS60serial_r2, METH_VARARGS},
{"close", (PyCFunction)PyS60serial_close, METH_VARARGS},
{"write", (PyCFunction)PyS60serial_write, METH_VARARGS},
{"cr", (PyCFunction)PyS60serial_cr, METH_VARARGS},
{0, 0} /* sentinel */
};
DL_EXPORT(void) init_PyS60serial()
{
PyObject* module = Py_InitModule("_PyS60serial",
(PyMethodDef*) PyS60serial_methods);
}
#ifndef EKA2
GLDEF_C TInt E32Dll(TDllReason)
{
return KErrNone;
}
#endif


Reply With Quote


, or maybe I'll use the audio cable exit from the phone (something is telling me i'll lose my phone doing that but I love to try!) 

