Forums | developer.brewmp.com Forums | developer.brewmp.com

Developer

Forums

We've been doing (or attempting ;-) some prototyping of BREW applications that connect to a PC via USB, and have been stymied by USB/IPort. If anyone could point us to answers to a couple questions that will be huge help:

Is there example BREW code available that communicates via IPort/USB?

Is there example windows code available that talks to a handset via USB?

We've been working with the LG Chocolate. We can load our BREW apps with the app loader, and run these apps on the handset. But when our BREW app tries to talk out the IPort (connected to the same PC now running our windows code) where see no traffic. IPort claims to be opened after a very brief wait.

Also, using a windows program and opening "COM9", as used by the app loader, we try to send AT commands to the ATCOP. We send "01AT$BREW" and received no response from the handset. Unfortunately I can't be 100% certain that our windows software works and that this command is reaching the handset.

We get the same results with the Motorola Razor.

Anyone have insight? Thank you!

It sounds like you're using the wrong COM port. If you connect AppLoader using QCOMOEM.dll, the port number used there (on most handsets, void where prohibited, etc.) is the "diag" port. Under the Modems control panel in Device Manager, you should see a modem corresponding with your device. Right click, select properties, click the modem tab, and that's the COM port you should use.
01AT$BREW is not a valid command. AT$BREW is. Once you successfully do AT$BREW, you'll be in the BREW Command Processor (BSCOP). It sounds like you have documentation on what to do from there (this is where you prepend the numbers to the commands, such as "01ver", or "02app").
SIO is a protected class. You must declare a dependency on AEECLSID_SERIAL in your mif in order to create it.
Below is a snippet of code I have from a file called siousage.c. I can't guarantee its correct, and it is certainly over-simplistic for a commercial app, but maybe it will be of some use.
I can probably give further pointers if there's something in particular you're confused about. Also, if you're writing an internal tool for the device, you may consider using the BTIL Development Kit. It takes care of all of the serial port/connectivity issues for you, provides reliability, and some other niceties (like the built-in ability to copy files, send events, start applets, etc.). Right now it doesn't work on certain devices, but most of those issues should be solved with the upcoming release.
// Our applet's structure
typedef struct SIOUsage
{
AEEApplet a;
IPort *piPort;
AEECallback cbReadable;
AEECallback cbWriteable;
SIOUsage;
static int SIOUsage_Init(SIOUsage *pme)
{
int nErr;
nErr = ISHELL_CreateInstance(pme->a.m_pIShell, AEECLSID_SERIAL,
(void**)&pSioPort->piPort);
if (nErr != SUCCESS)
{
return EFAILED;
}
// The following line opens the RS-232 serial port. To open the USB
// serial port, use AEESIO_PORT_USB1
nErr = IPORT_Open(pme->piPort, AEESIO_PORT_SIO1);
if (nErr != SUCCESS && nErr != AEEPORT_WAIT)
{
// There was some unknown error opening the port
DBGPRINTF("Error opening port");
return EFAILED;
}
// Setup our callbacks. These are called when there is *probably* data
// to be written or read.
CALLBACK_Init(&pme->cbReadable, SIOUsage_TryRead, (void*)pme);
CALLBACK_Init(&pme->cbWriteable, SIOUsage_TryWrite, (void*)pme);
IPORT_Readable(pme->piPort, &pme->cbReadable);
IPORT_Writeable(pme->piPort, &pme->cbWriteable);
// At this point, if nErr is AEEPORT_WAIT, the serial port is opening.
// We'll know this is complete when our cbWriteable callback fires.
// Normally, we'll receive AEEPORT_WAIT instead of SUCCESS.

static void SIOUsage_TryRead(void *po)
{
SIOUsage *pme = (SIOUsage*)po;
int32 dwRead;
char buf[100];
// We can *probably* read data here
dwRead = IPORT_Read(pme->piPort, buf, sizeof(buf));
// Log a message if we did read data
if (dwRead > 0)
{
DBGPRINTF("Read %ld bytes of data", dwRead);
}
// Remember that we need to reset our readable callback
IPORT_Readable(pme->piPort, &pme->cbReadable);

static void SIOUsage_TryWrite(void *po)
{
SIOUsage *pme = (SIOUsage*)po;
int32 dwWrite;
char *pBuf = "Hello World!";
// If you want to know if the port successfully got opened, do it here.
// what you want to do is nErr = IPORT_Open(pme->piPort, NULL);
// We can *probably* write data here
dwWrite = IPORT_Write(pme->piPort, pBuf, STRLEN(pBuf));
// Log a message if we did read data
if (dwWrite > 0)
{
DBGPRINTF("We wrote %ld bytes of data", dwWrite);
}
// Remember that we need to reset our writeable callback
IPORT_Writeable(pme->piPort, &pme->cbWriteable);

It sounds like you're using the wrong COM port. If you connect AppLoader using QCOMOEM.dll, the port number used there (on most handsets, void where prohibited, etc.) is the "diag" port. Under the Modems control panel in Device Manager, you should see a modem corresponding with your device. Right click, select properties, click the modem tab, and that's the COM port you should use.
01AT$BREW is not a valid command. AT$BREW is. Once you successfully do AT$BREW, you'll be in the BREW Command Processor (BSCOP). It sounds like you have documentation on what to do from there (this is where you prepend the numbers to the commands, such as "01ver", or "02app").
SIO is a protected class. You must declare a dependency on AEECLSID_SERIAL in your mif in order to create it.
Below is a snippet of code I have from a file called siousage.c. I can't guarantee its correct, and it is certainly over-simplistic for a commercial app, but maybe it will be of some use.
I can probably give further pointers if there's something in particular you're confused about. Also, if you're writing an internal tool for the device, you may consider using the BTIL Development Kit. It takes care of all of the serial port/connectivity issues for you, provides reliability, and some other niceties (like the built-in ability to copy files, send events, start applets, etc.). Right now it doesn't work on certain devices, but most of those issues should be solved with the upcoming release.
// Our applet's structure
typedef struct SIOUsage
{
AEEApplet a;
IPort *piPort;
AEECallback cbReadable;
AEECallback cbWriteable;
SIOUsage;
static int SIOUsage_Init(SIOUsage *pme)
{
int nErr;
nErr = ISHELL_CreateInstance(pme->a.m_pIShell, AEECLSID_SERIAL,
(void**)&pSioPort->piPort);
if (nErr != SUCCESS)
{
return EFAILED;
}
// The following line opens the RS-232 serial port. To open the USB
// serial port, use AEESIO_PORT_USB1
nErr = IPORT_Open(pme->piPort, AEESIO_PORT_SIO1);
if (nErr != SUCCESS && nErr != AEEPORT_WAIT)
{
// There was some unknown error opening the port
DBGPRINTF("Error opening port");
return EFAILED;
}
// Setup our callbacks. These are called when there is *probably* data
// to be written or read.
CALLBACK_Init(&pme->cbReadable, SIOUsage_TryRead, (void*)pme);
CALLBACK_Init(&pme->cbWriteable, SIOUsage_TryWrite, (void*)pme);
IPORT_Readable(pme->piPort, &pme->cbReadable);
IPORT_Writeable(pme->piPort, &pme->cbWriteable);
// At this point, if nErr is AEEPORT_WAIT, the serial port is opening.
// We'll know this is complete when our cbWriteable callback fires.
// Normally, we'll receive AEEPORT_WAIT instead of SUCCESS.

static void SIOUsage_TryRead(void *po)
{
SIOUsage *pme = (SIOUsage*)po;
int32 dwRead;
char buf[100];
// We can *probably* read data here
dwRead = IPORT_Read(pme->piPort, buf, sizeof(buf));
// Log a message if we did read data
if (dwRead > 0)
{
DBGPRINTF("Read %ld bytes of data", dwRead);
}
// Remember that we need to reset our readable callback
IPORT_Readable(pme->piPort, &pme->cbReadable);

static void SIOUsage_TryWrite(void *po)
{
SIOUsage *pme = (SIOUsage*)po;
int32 dwWrite;
char *pBuf = "Hello World!";
// If you want to know if the port successfully got opened, do it here.
// what you want to do is nErr = IPORT_Open(pme->piPort, NULL);
// We can *probably* write data here
dwWrite = IPORT_Write(pme->piPort, pBuf, STRLEN(pBuf));
// Log a message if we did read data
if (dwWrite > 0)
{
DBGPRINTF("We wrote %ld bytes of data", dwWrite);
}
// Remember that we need to reset our writeable callback
IPORT_Writeable(pme->piPort, &pme->cbWriteable);

I was using the wrong COM port. Changing to COM8 was the key.
Thanks for the help!!
CS

I was using the wrong COM port. Changing to COM8 was the key.
Thanks for the help!!
CS

HI toddb,
The snippet which u has given above is very useful for me.But i have a dout in this given below quote. I don't understand what this third parameter contains in this ISHELL_CreateInstance() method. Plz tell me to know about this.
Quote:nErr = ISHELL_CreateInstance(pme->a.m_pIShell, AEECLSID_SERIAL,
(void**)&pSioPort->piPort);
If u can plz give me Brief description about this snippet which u has given above.
Thank u in advance
With Regards,
Vishnu

HI toddb,
The snippet which u has given above is very useful for me.But i have a dout in this given below quote. I don't understand what this third parameter contains in this ISHELL_CreateInstance() method. Plz tell me to know about this.
Quote:nErr = ISHELL_CreateInstance(pme->a.m_pIShell, AEECLSID_SERIAL,
(void**)&pSioPort->piPort);
If u can plz give me Brief description about this snippet which u has given above.
Thank u in advance
With Regards,
Vishnu

Serial data is implemented by the class represented by AEECLSID_SERIAL. The primary interface for the class is an IPort interface.
The second part of your question is really about interface-based programming. IPort is an abstract BREW interface that represents a 2-way data stream, much like a file descriptor. Several BREW interfaces inherit (or use directly) the IPORT interface so that sending/receiving data can happen in a consistent manner.
Specifically you asked about ISockPort. ISockPort inherits from IPort, so you can use a ISockPort* pointer for any function that takes an IPort* pointer, but the reverse is not true.
Other IPorts:
=========
AEECLSID_SERIAL uses IPort directly to send data to and from a RS232, IrDA, or USB serial port.
AEECLSID_FILEPORT uses IFilePort to write data to and read data from a file.
AEECLSID_FIFO uses IPort directly to send data to and from another BREW application.
AEECLSID_SOCKPORT uses the ISockPort interface to write data and read data from a TCP or UDP network connection.
Each of these interfaces inherits from IPort, so you can write some very powerful code based around that. For instance you could write a logging function that takes an IPort as an argument. You can then easily change whether it logs to a network or to a file or to a serial port.

Serial data is implemented by the class represented by AEECLSID_SERIAL. The primary interface for the class is an IPort interface.
The second part of your question is really about interface-based programming. IPort is an abstract BREW interface that represents a 2-way data stream, much like a file descriptor. Several BREW interfaces inherit (or use directly) the IPORT interface so that sending/receiving data can happen in a consistent manner.
Specifically you asked about ISockPort. ISockPort inherits from IPort, so you can use a ISockPort* pointer for any function that takes an IPort* pointer, but the reverse is not true.
Other IPorts:
=========
AEECLSID_SERIAL uses IPort directly to send data to and from a RS232, IrDA, or USB serial port.
AEECLSID_FILEPORT uses IFilePort to write data to and read data from a file.
AEECLSID_FIFO uses IPort directly to send data to and from another BREW application.
AEECLSID_SOCKPORT uses the ISockPort interface to write data and read data from a TCP or UDP network connection.
Each of these interfaces inherits from IPort, so you can write some very powerful code based around that. For instance you could write a logging function that takes an IPort as an argument. You can then easily change whether it logs to a network or to a file or to a serial port.

Hi,
Thank u for your valuable reply it is very helpful to me. I implemented the code u given above it is compiled well. But I have problem that it is not creating the instance. It is returning some positive integer value like this 1241908.Plz help me to solve this problem.
And one more thing I have to know i.e., where I should assign the Port number or name in this code.
I am getting problem in this code which i specified below.
Quote:static int SIOUsage_Init(SIOUsage* pme)
{
int nErr;
//
DBGPRINTF("Function Called PME:%X",&pme->piPort);
nErr = ISHELL_CreateInstance(pme->piShell,AEECLSID_SERIAL, (void**)&(pme->piPort));
if (nErr != SUCCESS)
{
DBGPRINTF("return EFAILED....................");
return EFAILED;
}
. . . .
. . . .
return SUCCESS;

Thanks in advance,
With Regards,
Vishnu.

Hi,
Thank u for your valuable reply it is very helpful to me. I implemented the code u given above it is compiled well. But I have problem that it is not creating the instance. It is returning some positive integer value like this 1241908.Plz help me to solve this problem.
And one more thing I have to know i.e., where I should assign the Port number or name in this code.
I am getting problem in this code which i specified below.
Quote:static int SIOUsage_Init(SIOUsage* pme)
{
int nErr;
//
DBGPRINTF("Function Called PME:%X",&pme->piPort);
nErr = ISHELL_CreateInstance(pme->piShell,AEECLSID_SERIAL, (void**)&(pme->piPort));
if (nErr != SUCCESS)
{
DBGPRINTF("return EFAILED....................");
return EFAILED;
}
. . . .
. . . .
return SUCCESS;

Thanks in advance,
With Regards,
Vishnu.

Hi,
I got it. It is working fine. Just I set the dependency in MIF file.
Thank U,
With Regards,
Vishnu.

Hi,
I got it. It is working fine. Just I set the dependency in MIF file.
Thank U,
With Regards,
Vishnu.

Hi toddb,
Thank u for that snippet, Code u has given is working fine and it is writing the data in buffer but is not reading it from buffer.IPort_Read is returning -2. Plz help me how to read the data from Buffer.
One more thing what i have to know is, Can i write (IPORT_Write) datas using RS32 serial port (com1) and can i read (IPORT_Read) datas using USB(COM2). Is it possible ? Plz give me some detail about my queries.
Thank u in advance.
With Regards,
Vishnu

Hi toddb,
Thank u for that snippet, Code u has given is working fine and it is writing the data in buffer but is not reading it from buffer.IPort_Read is returning -2. Plz help me how to read the data from Buffer.
One more thing what i have to know is, Can i write (IPORT_Write) datas using RS32 serial port (com1) and can i read (IPORT_Read) datas using USB(COM2). Is it possible ? Plz give me some detail about my queries.
Thank u in advance.
With Regards,
Vishnu

-2, (IPORT_WAIT), per the documentation, means there's no data to be read at that moment. The code above does the IPORT_Readable() callback, which will tell you when the API will probably return data. In the readable callback, call IPort_Read.
EDIT: Your second point brings up a good point that isn't really publicized. On most devices, they can only open one serial port at a time. So while the APIs don't stop you from reading from PORT1 and writing to USB1, the hardware/software limitations on the device do.

-2, (IPORT_WAIT), per the documentation, means there's no data to be read at that moment. The code above does the IPORT_Readable() callback, which will tell you when the API will probably return data. In the readable callback, call IPort_Read.
EDIT: Your second point brings up a good point that isn't really publicized. On most devices, they can only open one serial port at a time. So while the APIs don't stop you from reading from PORT1 and writing to USB1, the hardware/software limitations on the device do.

Hi tod,
Thanks for ur inforamtion. Can i send second parameter as integer or hexadecimal in IPort_Write() function.If i can what is the maximum range of value i can send. Plz tell me about this.
Thanks in advance.
With Regards,
Vishnu.

Hi tod,
Thanks for ur inforamtion. Can i send second parameter as integer or hexadecimal in IPort_Write() function.If i can what is the maximum range of value i can send. Plz tell me about this.
Thanks in advance.
With Regards,
Vishnu.

Hi toddb,
when I use
result = IPORT_Open( pCommConn->pIPort, AEESIO_PORT_SIO1);
the result is SUCCESS,
but for USB
result = IPORT_Open( pCommConn->pIPort, AEESIO_PORT_USB1);
it returns 39.
#define ENOSUCH 39 // No such name/port/socket/service exists or valid
Is there something else need to add for USB support?
BTW, I just run my applet on windows emulator, not real device.

Hi toddb,
when I use
result = IPORT_Open( pCommConn->pIPort, AEESIO_PORT_SIO1);
the result is SUCCESS,
but for USB
result = IPORT_Open( pCommConn->pIPort, AEESIO_PORT_USB1);
it returns 39.
#define ENOSUCH 39 // No such name/port/socket/service exists or valid
Is there something else need to add for USB support?
BTW, I just run my applet on windows emulator, not real device.

Hi toddb (and the rest of the forum).
I've used your code snippet above, and it works great! so, thanks alot!
However, I do have a question about the code, for some reason, the moment I launch my app, and open the USB, the write callback is called several times, until there is no data... (error -2), however, I did not call any code on the PC end to read data from the deivce (which by my logic should trigger the write callback on the device end).
Amy I doing something wrong here?
Thanks in advance...

Hi toddb (and the rest of the forum).
I've used your code snippet above, and it works great! so, thanks alot!
However, I do have a question about the code, for some reason, the moment I launch my app, and open the USB, the write callback is called several times, until there is no data... (error -2), however, I did not call any code on the PC end to read data from the deivce (which by my logic should trigger the write callback on the device end).
Amy I doing something wrong here?
Thanks in advance...