Related
1) Hi, we works with Pocket PC 2003 (Embedded Visual C++ 4.0). Our target is perform a data call over integrated cellular line. We read that the right mean is TAPI (XDA-Developers forum) because COM2 seem to be owned by RIL layer. We wrote a test program which handles a data call answer. We get the serial port handle returned by "lineGetID()" function for current data call, but when we try to use it through standard communication APIs ("WriteFile()" and "ReadFile()") it doesn't work (no data is read or write from port handle, but there aren't errors returned by APIs). Same code seems to work fine on a HP IPAQ 2210 with a Compact Flash GSM/GPRS card. How can we transfer data so?
2) We noticed a phone answering process is alive (CPROG.EXE) that takes calls' control. We kill this process when we make our tests, but it backs to life after some minutes. How can we take real calls' control?
3) Is the integrated cellular modem Hayes compatible? Is there a way to directly send AT commands to integrated cellular modem?
4) DCB structure "PortDCB" we pass to "SetCommState()" is the following:
PortDCB.DCBlength = sizeof (DCB);
PortDCB.BaudRate = 9600;
PortDCB.fBinary = TRUE;
PortDCB.fParity = TRUE;
PortDCB.fOutxCtsFlow = FALSE;
PortDCB.fOutxDsrFlow = FALSE;
PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
PortDCB.fDsrSensitivity = FALSE;
PortDCB.fTXContinueOnXoff = TRUE;
PortDCB.fOutX = FALSE;
PortDCB.fInX = FALSE;
PortDCB.fErrorChar = FALSE;
PortDCB.fNull = FALSE;
PortDCB.fRtsControl = RTS_CONTROL_ENABLE;
PortDCB.fAbortOnError = FALSE;
PortDCB.ByteSize = 8;
PortDCB.Parity = NOPARITY;
PortDCB.StopBits = ONESTOPBIT;
Is it correct?
Can anybody help me?
Matthew
This DCB params seem do right job....
Code:
PortDCB.BaudRate = 115200;
PortDCB.fBinary = TRUE;
PortDCB.fParity = FALSE;
//PortDCB.fParity = TRUE;
PortDCB.fOutxCtsFlow = FALSE;
PortDCB.fOutxDsrFlow = FALSE;
PortDCB.fDtrControl = DTR_CONTROL_ENABLE;
PortDCB.fDsrSensitivity = FALSE;
//PortDCB.fDsrSensitivity = TRUE;
PortDCB.fTXContinueOnXoff = TRUE;
//PortDCB.fTXContinueOnXoff = FALSE;
PortDCB.fOutX = FALSE;
PortDCB.fInX = FALSE;
PortDCB.fErrorChar = FALSE;
PortDCB.fNull = FALSE;
PortDCB.fRtsControl = RTS_CONTROL_DISABLE;
PortDCB.fAbortOnError = FALSE;
PortDCB.ByteSize = 8;
PortDCB.Parity = NOPARITY;
PortDCB.StopBits = ONESTOPBIT;
problem one shuold be solved ...Hi
Your DCB parameters worked fine.
Hi Matthew.
Your parameters worked fine with my application, i was teting an IMate and you helped me a lot with my next product version.
Thank you.
Cesar Bremer Pinheiro
Bremer Serv. Emp. Ltda.
Raseac Division.
http://www.raseac.com.br
Dear Matthew,
Hi,
I created a similar application to make a call from one PPC to another using data link. The problem is my program couldn't detect incoming calls. Would you please help me solve this issue?
Do you have any source code that I can learn from it? Also which method did you use? TAPI? COM port? RIL?
I'm very confused. Please help....
Best regards,
A. Riazi
Why is your baudrate 115200 when a CSD connection through TAPI is only at 9600 ?
cause it's TAPI
you can't select bearer capabilities
if you wana select rate use RIL or direct access to COM-ports
mathews help!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
hi,
i am facing a similar problem cant send data through writefile api on cellular line
these r code snippets form my cod e
if(dwReturn =lineOpen (
g_hLineApp, // Usage handle for TAPI
g_dwCurrentLineID, // Cannot use the LINEMAPPER value
&g_CurrentLineInfo.hLine, // Line handle
g_CurrentLineInfo.dwAPIVersion,
// API version number
0, // Must set to zero for Windows CE
0, // No data passed back
LINECALLPRIVILEGE_NONE, // Can only make an outgoing call
0, // Media mode
NULL))
g_MakeCallRequestID = lineMakeCall (g_CurrentLineInfo.hLine,
&g_hCall,
szDialablePhoneNum,
0,
NULL);
dwRet =lineGetID(g_CurrentLineInfo.hLine, 0, 0, LINECALLSELECT_LINE, lpVarString,TEXT("comm/datamodem"));
till this its ok it returns a valid comm handle
after that it sends th data over the connected call but doesnt receive anythinga t the other end ...
the problem might be to give a call handle and LINECALLSELECT_CALL in linegteid func tion i tried it but when i use it fails saying cannot obtain the handle .......now i don understand whether its the problem of not obtaining a handle or whether linehandle will work but problem is in communication ...
plz help and add some code snippets for the communication
firstly have you set up the following...
LPLINECALLPARAMS CallParams;
CallParams=(LPLINECALLPARAMS)malloc(sizeof(LINECALLPARAMS)+1024);
memset(CallParams,0,sizeof(LINECALLPARAMS)+1024);
CallParams->dwTotalSize = sizeof(LINECALLPARAMS)+1024;
// This is where we configure the line for DATAMODEM usage.
//its important to note that if you attempt to make a call
//using LINEMEDIAMODE_DATAMODEM, the line must be opened in
//that way to begin with or nothing will happen. ie open lines
//corresponding to what you plan to makecall with.
CallParams->dwBearerMode = LINEBEARERMODE_VOICE;//over voice call
CallParams->dwMediaMode = LINEMEDIAMODE_DATAMODEM;//data transmition
//LINEMEDIAMODE_INTERACTIVEVOICE;//for voice
//specify that we only want to use a call that is not alreay in use.
//Otherwise it can take over calls that are in progress
CallParams->dwCallParamFlags = LINECALLPARAMFLAGS_IDLE;
//specify to use the first address
CallParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID;
CallParams->dwAddressID = 0;
next check the line you want to use and make sure...
if(lpDevCaps->dwBearerModes & callModeData)//datamode
{
if(lpDevCaps->dwBearerModes & callModeVoice)
{
//then check the media mode
if(lpDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM)
{
if(lpDevCaps->dwMediaModes & LINEMEDIAMODE_INTERACTIVEVOICE)
{
//use it
}
}
}
}
next when you get an incoming call etc get the handle......
HANDLE myTapiManager::getHandle()
{
HANDLE hModem=NULL;
CString name="";
classType="comm/datamodem";
DWORD dwSize = sizeof(VARSTRING) + 2048;
DWORD dwRet = 0;
do
{
LPVARSTRING lpVarString = (LPVARSTRING) new BYTE[dwSize];
lpVarString->dwTotalSize = dwSize;
//the commented out values are what microsoft seem to say
//but cause it to return no handle but only the device class name
dwRet = ::lineGetID(/*hOpenedLine*/NULL, 0,hCall,LINECALLSELECT_CALL /*LINECALLSELECT_LINE*/, lpVarString,
classType);
if ( dwRet == 0 )
{
hModem= * (HANDLE*) ((char*) lpVarString + lpVarString->dwStringOffset);
name= * (LPTSTR) ((char*) lpVarString + lpVarString->dwStringOffset + sizeof(HANDLE));
if(hModem==NULL)
{
MessageBox(NULL,_T("null handle"),_T("handle"),MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
}
else
{
MessageBox(NULL,_T("non null handle, about to call init on port"),_T("handle"),MB_OK|MB_SETFOREGROUND|MB_TOPMOST);
hSerialHandle=hModem;
//you must initialize the port but I do not show it here
initializeIOTimeOuts();
}
break;
}
else if ( dwRet == LINEERR_STRUCTURETOOSMALL )
{
dwSize = lpVarString->dwNeededSize;
delete lpVarString;
lpVarString = NULL;
continue;
}
else
{
// handle errors.........
//
hModem=NULL;
}
}
while (1);
return hModem;
}
this works for me. One problem you may be having is the timing. If you get the handle when the call is offering it will be useless. You must ensure that the call is connected, use the LINECALLSTATE_CONNECTED for this.
cprog dose not effect the opperation of your program, only its ui.
Have you looked at the zip I put in this post ?
http://forum.xda-developers.com/viewtopic.php?t=18978
It may help you with the sending part and getting a handle to Readfile/writefile.
I have never worked on the anwering side so I know nothing on that.
to answer the call that is offering, use LineAnswer. I have tried LinePickup but it has not done what I want. When using lineanswer be aware that the os has already set the number of rings it will ring before the call is actually answered after you answer it. It is normally changed through the phone settings but you can do it programatically if you wish.
Also, you have not mentioned what you are doing with regards to threads. The first time I tried using tapi I spent a lot of time avoiding using multiple threads but it is impracticle. A good number would be 1 for the ui 1 for the line status and 1 for data transfer. Getting your serial handle would the require carefull synchronization.
I have not found benefit in altering any of the port settings. The time-outs for the read/write can make a huge difference though.
Have you checked if there is a class name following the handle in the LPVARSTRING? I have found that if you are doing everything correct except the timing, the name is added but not the handle. This means that the name would be 4 places sooner than it should. In that case the name is in the place where the handle should be and the call still succeeded. Try writing to the port using a string instead of a handle and see how far you get(kidding). To test it just treat the handle you have got as if it where a string and put it in a messagebox. If you can read it then your timing is off.
Lastly your problem could come from how you are setting the api version. Have you been checking the errors generated after all your api calls. There are a lot for tapi that tell you most of what is going on. I have noticed that if you are using the event method for getting line state messages from tapi (ie the correct time to grab the handle) there is something wrong with the way the api version gets negotiated. The event method is part of tapi 2.0 i think so it should be expected that an api version of at least 2.0 is a good version to aim for. For win ce 3.0 docs say that 2.0 is fully supported and parts of 2.1. This is not what actually happens though, I have found that I can't get the event method to work at all (among other things) if I don't pass a min version of 1.1 and a max version of 1.3. This is bizar because by that input tapi should not use any features above 1.3 :?:
guys i ve been trying to set up call params
//Configure line device for a data modem
memset(&LineCallParams, 0, sizeof(LineCallParams));
LineCallParams.dwTotalSize = sizeof(LineCallParams);
LineCallParams.dwBearerMode = LINEBEARERMODE_VOICE;
LineCallParams.dwMediaMode = LINEMEDIAMODE_DATAMODEM;
LineCallParams.dwCallParamFlags = LINECALLPARAMFLAGS_IDLE;
//If multiple addresses on the line, use the first address
LineCallParams.dwAddressMode = LINEADDRESSMODE_ADDRESSID;
LineCallParams.dwAddressID = 0;
the problem is when i pass the lpparam instead of null it reaches to dialing the number and says disconnected: unreachable ..
There is no error while lineopen is passed with LINEMEDIAMODE_DATAMODEM as the 8th parameter i think it shoudl have given an error of media mode not supported at that point only ....but it didnt .....it opened the line fine
when i did not set the datamodem media mode in call params and rest remain as it is ..........the call works fine and is connected ....is it because the datacall facility is not supported and if it is not how can it be activated ....
lReturn = lineOpen(m_hLineApp, m_dwDeviceID, &m_hLine, m_dwAPIVersion, 0 , 0,
LINECALLPRIVILEGE_NONE, LINEMEDIAMODE_DATAMODEM, 0);
g_MakeCallRequestID = lineMakeCall (g_CurrentLineInfo.hLine,
&g_hCall,
szDialablePhoneNum,
0,
NULL); // NULL for default voice call
/**************************/
// lpCallParams);
Firstly, is the phone you are trying to dial a ppc. If yes... the ppc you wish to be the one that answers the call must have opened the line the same way as the dialing one, ie supporting data. If not then it will not even ring when a data call is offering and you will never know if your call was really made.
next look at lineopen.
long opnResult=lineOpen(hLineApp,
deviceID,
&hOpenedLine,
apiNegotiatedForUsedDevice,
0,//not used at all
1,//not used by tapi, but is passed back to this //application to help identify the source of the messages.
//in each line state message. It can be used
//to make sure the message is from a line
//opened by this app.
LINECALLPRIVILEGE_OWNER,// tells it can //accept calls.
LINEMEDIAMODE_DATAMODEM,
NULL);
almost the same but try LINECALLPRIVILEGE_OWNER. This must be set on the receiving end but I also set it on the dialing end.
If the media mode is not supported you will get an error message to tell so. That is the primary way my programs determine the identity of the line to use.
What is the device you are using? I have got bi-directional data transfer to work between ppc 2002 (xda I) and wm2003 se (xda mini). Before 2002 not as many features are supported.
also your call params may be too small
try adding a litle to the end
LPLINECALLPARAMS CallParams;
CallParams=(LPLINECALLPARAMS)malloc(sizeof(LINECALLPARAMS)+1024);
memset(CallParams,0,sizeof(LINECALLPARAMS)+1024);
CallParams->dwTotalSize = sizeof(LINECALLPARAMS)+1024;
.
.
.
.
and what about the number to dial in the call params
// Address to dial
//set its location to be after the normal end of the structure
CallParams->dwDisplayableAddressOffset = sizeof(LINECALLPARAMS);
CallParams->dwDisplayableAddressSize = strlen(szPhNumber);
strcpy((LPSTR)CallParams+sizeof(LINECALLPARAMS), szPhNumber));
then pass the szPhNumber into linemakecall, remember that ppc version
takes unicode.
i am trying to pass data from pocket pc to my pc
this is whole part
LPLINETRANSLATEOUTPUT lpTransOutput = NULL;
// Call translate address before dialing.
do
{
// Allocate memory for lpTransOutput.
if (!(lpTransOutput = (LPLINETRANSLATEOUTPUT) LocalAlloc (
LPTR,
dwSizeOfTransOut)))
{
ErrorBox(TEXT("translate fails "));
goto exit;
}
lpTransOutput->dwTotalSize = dwSizeOfTransOut;
if (dwReturn = lineTranslateAddress (
g_hLineApp, // Usage handle for TAPI
g_dwCurrentLineID, // Line device identifier
g_CurrentLineInfo.dwAPIVersion,
// Highest TAPI version supported
lpszPhoneNum, // Address to be translated
0, // Must be 0 for Windows CE
0, // No associated operations
lpTransOutput)) // Result of the address translation
{
ErrorBox(TEXT("lineTranslateAddress fails "));
goto exit;
}
if (lpTransOutput->dwNeededSize <= lpTransOutput->dwTotalSize)
break;
else
{
dwSizeOfTransOut = lpTransOutput->dwNeededSize;
LocalFree (lpTransOutput);
lpTransOutput = NULL;
}
} while (TRUE);
dwSizeOfCallParams += lpTransOutput->dwDisplayableStringSize;
if (!(lpCallParams = (LPLINECALLPARAMS) LocalAlloc (
LPTR,
dwSizeOfCallParams)))
{
ErrorBox(TEXT("lineTranslateAddress open fails "));
goto exit;
}
ZeroMemory(lpCallParams, dwSizeOfCallParams);
// Set the call parameters.
lpCallParams->dwTotalSize = dwSizeOfCallParams;
lpCallParams->dwBearerMode = LINEBEARERMODE_VOICE;
lpCallParams->dwMediaMode = LINEMEDIAMODE_DATAMODEM ;
lpCallParams->dwCallParamFlags = LINECALLPARAMFLAGS_IDLE;
lpCallParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID;
lpCallParams->dwAddressID = g_dwCurrentLineAddr;
lpCallParams->dwDisplayableAddressSize =
lpTransOutput->dwDisplayableStringSize;
lpCallParams->dwDisplayableAddressOffset = sizeof (LINECALLPARAMS);
// Save the translated phone number for dialing.
lstrcpy (szDialablePhoneNum,
(LPTSTR) ((LPBYTE) lpTransOutput +
lpTransOutput->dwDialableStringOffset));
memcpy((LPBYTE) lpCallParams + lpCallParams->dwDisplayableAddressOffset,
(LPBYTE) lpTransOutput + lpTransOutput->dwDisplayableStringOffset,
lpTransOutput->dwDisplayableStringSize);
// Make the phone call. lpCallParams should be NULL if the default
// call setup parameters are requested.
g_MakeCallRequestID = lineMakeCall (g_CurrentLineInfo.hLine,
&g_hCall,
szDialablePhoneNum,
0,
NULL); // NULL for default voice call
/**************************/
// lpCallParams);
plz suggest if i need to change anything but as the call is successfully connected when only media mode is not set i guess problem is not with the memory location or anything but lies with the provider not sure ...............
or better maybe if u can suggest how i can do settings on my pocket pc for data calls
If you can't make a Data Modem type call, but you can make a voice call - Then are you sure you have Data Enabled on your Sim.
I'm sure I had that un-reachable error ages ago and it was due to not having Data Enabled. You have to contact your Sim provider to do that.
I have never included the lineTranslateAddress, i just put it in the way the user entered it( with a little error checking). If it works for voice though it must be OK.
With the sim, I have done this using 3 different sims and never had to set anything special on it. I could be lucky I guess and had sims already enabled. I doubt it though because one is 7 years old pre paid and not had any change since purchase. The second in a new pre paid and the 3rd is a full gprs enabled(not that gprs has anything to do with this). There should not be anything in the os to set either as when you do what you have done it is doing the "setup" just programatically.
I remember reading somewhere that the network had to support it but I can't be more specific.
What is your network? What is your device? what is your os?
When you say the voice call is connected what do you mean?..
1)your program at the other end answered.
2)the phone app on the other end answered.
3)your dialing end app received the connected message.
4)the returned value from linmakecall was > (-1).
5)some phone hardware on a real phone answered.
6) (my favourite way) the monitor next to your phone started buzzing, proving something was going on. Thats how I test my gprs connectivity :lol:
XDA Developers,
Years ago I downloaded the RIL .dll and API from this site. Then it was only half complete and I had to patch it my self.
I am sure development has been completed since then.
Can anybody tell me if RIL is still maintained by this site? In which case, where can I get it?
Specifically I need signal quality on XDA II upwards. If anybody can help me?
Kind Regards,
Ben
After posting, my text RIL was shown with a link to most of the information.
There is one think I can't understand. The stucture returned as as follows:
int nMinSignalStrength; // @field TBD
int nMaxSignalStrength; // @field TBD
int nLowSignalStrength; // @field TBD
int nHighSignalStrength; // @field TBD
Which have the values (On XDA IIs) of -113, -51, -110, -60
Would any member know what the meaning of these values is?
I have then tried to convert the quality to a percentage. But the percentage always reads way to high, or zero.
My guess is that these are DB and therefore logarithmic. Would any member know how to convert to a linar scale?
My guess is something like: log10(n / 3) where n is any of the above or retuned figure.
Any ideas would be very useful!
Regards, Ben.
Hi,
Code:
HRESULT RIL_GetSignalQuality(
HRIL hRil // @parm handle to RIL instance returned by <f RIL_Initialize>
);
returns the following structure:
Code:
typedef struct rilsignalquality_tag {
DWORD cbSize; // @field structure size in bytes
DWORD dwParams; // @field indicates valid parameters
int nSignalStrength; // @field TBD
int nMinSignalStrength; // @field TBD
int nMaxSignalStrength; // @field TBD
DWORD dwBitErrorRate; // @field bit error rate in 1/100 of a percent
int nLowSignalStrength; // @field TBD
int nHighSignalStrength; // @field TBD
} RILSIGNALQUALITY, *LPRILSIGNALQUALITY;
Why don't you just use nSignalStrength? Sounds pretty simple and linear to me? Nothing to calculate...
In trying to make my posting simple. I think I forgot to clarify my problem
First is the problem that the nSignalStrength falls between two values.
But there are two fields it can fall between:
nMinSignalStrength <= nSignalStrength <= nMaxSignalStrength
nLowSignalStrength <= nSignalStrength <= nHighSignalStrength
Which one should be used? Why are there two?
Secondly, I want to show a percentage result between one of the above. But these figures are, I belive, Decibels (BD). Each 3 DB = a doubling of the value. So 1 = 10%, 4 = 20%, 7 = 40% etc...
Therefore a liniar percent placement of nSignalStrengh tells me nothing. Most values are close to Max, and then suddenly zero.
My math is a little rusty I was hoping somebody may have a nice function for returning the linear range from the logarithmic rage….
Thanks again to any members who can offer some help
Ben
Hmm... but what if min and max are just values currently encountered in your local cell? When you move to another cell you may receive different min/max values. Or maybe these are the values of the farest and nearest cell? I don't know either, but your explanation of min/max sounds worse to me than does mine...
This could be correct. The values I have are on my XDA IIs using O2 are:
Min -113
Low -110
High -60
Max -51
Therefore:
Min < Low < nSignalStrength < High < Max
So I am using Low = 0% and High = 100%. But this returnes figures of above 50% when signal is quite low.
I think the linear conversion is exp(value / 3)
Therefore percent is:
percent = (exp(nSignalStrength / 3) - exp(Low / 3)) / (exp(high / 3) - exp(Low / 3)) * 100;
Which seems to give better figures. But I am not sure how accurate it is..
Any experts on signal quality out there, I'd love to hear from them!
Ben
If anybody is following this thread, this *seems* to return a good percentage for signal quality. I am not sure of the quality or accuracy. But it works
static double dValue, dMax;
dValue = (int)data->nSignalStrength; // (int) to convert twos complement signed integer correctly.
dMax = (int)data->nHighSignalStrength; // (int) to convert twos complement signed integer correctly.
dValue -= (int)data->nLowSignalStrength;
dMax -= (int)data->nLowSignalStrength;
dValue = pow(dValue / -3.0, 2);
dMax = pow(dMax / -3.0, 2);
dValue /= dMax;
dValue *= 100;
if (dValue > 100) dValue = 100; // never
if (dValue < 0) dValue = 0; // never
Regards,
Ben
Hi there, i've been following this thread with interest I have a very limited knowlege of C++ but not even on the PPC.
Would you mind attaching or even PMing your cpp so i could possibly learn more ?
I find i learn more by examples, and am quite interested in making an application that can disable the radio then re-enable it after a set ammount of time (so i can swap between sims, i have a dual sim adapter)
Best thing to do is follow the sample code supplied by these nice gues from xda-developers, by clicking on this RIL link.
BUT replace the ril.h in the .zip archive with the ril.h you will find from the link.
(nb: if the author of this .zip archive is reading, it's way out of date to the ril.h on this site. ps, hows the ril development going?)
If you get the sample code working, this will give you some idea of what is possible. Your options may not be possible. But look at the ril.h and the functions listed. If one of them does what you want, give it a go.
Regards,
Ben
Hey all,
I'm trying to register an application to run during a Windows Mobile event using CeRunAppAtEvent (from CoreDll.dll). I'm having difficulty getting this to happen.
Here is the syntax for the native method:
Code:
BOOL CeRunAppAtEvent(
TCHAR* pwszAppName,
LONG lWhichEvent
);
Here is the code in my application (C#):
Code:
[DllImport("coredll.dll", EntryPoint = "CeRunAppAtEvent", SetLastError = true)]
private static extern bool CeRunAppAtEvent(string pwszAppName, int lWhichEvent);
private void menuItem1_Click(object sender, EventArgs e)
{
if (CeRunAppAtEvent(@"\Windows\Calc.exe", 3))
{
MessageBox.Show("Event registered!");
}
else
{
MessageBox.Show("Event did not register.");
}
}
Note that I'm using the argument '3' for lWhichEvent, which is based upon this understanding of how lWhichEvent argument works:
Code:
> NOTIFICATION_EVENT_NONE = 0,
> NOTIFICATION_EVENT_TIME_CHANGE = 1,
> NOTIFICATION_EVENT_SYNC_END = 2,
> NOTIFICATION_EVENT_ON_AC_POWER = 3,
> NOTIFICATION_EVENT_OFF_AC_POWER = 4,
> NOTIFICATION_EVENT_NET_CONNECT = 5,
> NOTIFICATION_EVENT_NET_DISCONNECT = 6,
> NOTIFICATION_EVENT_DEVICE_CHANGE = 7,
> NOTIFICATION_EVENT_IR_DISCOVERED = 8,
> NOTIFICATION_EVENT_RS232_DETECTED = 9,
> NOTIFICATION_EVENT_RESTORE_END = 10,
> NOTIFICATION_EVENT_WAKEUP = 11,
> NOTIFICATION_EVENT_TZ_CHANGE = 12,
> NOTIFICATION_EVENT_MACHINE_NAME_CHANGE = 13
I've tried registering Calc and a few other applications unsuccessfully--the program tells me the event registers (so the method call is returning true), yet the applications do not launch upon the event change (plugging into AC power, for example). Any ideas to what I'm doing wrong?
Bump. Any ideas?
Hello shidell
I also found, that not all possible wakeups are possible on every device. I assume it is OEM related and the implementation of these events is not mandatory for WM platform builds.
See also hjgode.de/dev and look for iRunAtEvent and iRunOnEnet. The latter is a workaround for enet detection.
I recently did try to use ON_AC_POWER and it did not work. The event registration was OK but the event was not signaled on AC power connection. I worked around it and changed my code to run on wakeup, which works OK on this particular device (CK61 running WinCE5).
As a workaround, you could go the way I did in iRunOnEnet. Instead of watching the enet connection you have to check the PowerStatus structure for ON AC POWER.
regards
josef
You are right, not every event can be handled with CeRunAppAtEvent and here are the events that have to works on every device:
Code:
Const NONE = 0
Const TIME_CHANGE = 1
Const SYNC_END = 2
Const DEVICE_CHANGE = 7
Const RS232_DETECTED = 9
Const RESTORE_END = 10
Const WAKEUP = 11
Const TIME_ZONE_CHANGE = 12
Good approach will be to check your application's path by using:
Code:
System.IO.File.Exists(<application>)
because for example in my ROM that "calc.exe" is actually "calculator.exe"... and of course CeRunAppAtEvent will return True, because the event handler will be registered no matter file exists or not
Hope this helps.
Best regards,
aDEO
I am currently working on my "SciLor's WiMoBlue". The new protocol is ready. Everything works fine, until I send much data at the same time.
For example if I try to send an image in that way:
Code:
Public Sub SendImage(ByVal Image As Bitmap, ByVal Position As Point, ByVal Format As ImageFormat)
Dim PosX, PosY, Width, Height As Byte()
Dim ImageStream As New IO.MemoryStream
Dim ImageLength As Integer
Dim ImageLengthBytes As Byte()
Dim ImageBuffer(MaxChunkSize - HeaderSize - 1) As Byte
PosX = BitConverter.GetBytes(Position.X)
PosY = BitConverter.GetBytes(Position.Y)
Width = BitConverter.GetBytes(Image.Width)
Height = BitConverter.GetBytes(Image.Height)
Image.Save(ImageStream, ImageFormat2ImagingFormat(Format))
ImageStream.Seek(0, SeekOrigin.Begin)
ImageLength = ImageStream.Length
ImageLengthBytes = BitConverter.GetBytes(ImageLength)
SendData(BuildCommand(BaseProtocol.Image, ImageProtocol.Initiate, CombineBytes(PosX, PosY, Width, Height, ImageLengthBytes)))
Thread.Sleep(2000)
Dim DataPos As Integer
For DataPos = 0 To ImageStream.Length - MaxChunkSize - HeaderSize - 1 Step MaxChunkSize - HeaderSize
ImageStream.Read(ImageBuffer, 0, MaxChunkSize - HeaderSize)
SendData(BuildCommand(BaseProtocol.Image, ImageProtocol.Data, ImageBuffer))
'WaitForNextChunk = True
'Do While WaitForNextChunk = True
'Loop
'Thread.Sleep(2000)
Next
ImageBuffer = New Byte(ImageLength - DataPos - 1) {}
ImageStream.Read(ImageBuffer, 0, ImageBuffer.Length)
SendData(BuildCommand(BaseProtocol.Image, ImageProtocol.End, ImageBuffer))
End Sub
SendData:
Code:
If Data.Length > MaxChunkSize Then
MsgBox("Data to long... " & vbNewLine & "SendSize:" & Data.Length & vbNewLine & "MaxSize:" & MaxChunkSize)
Else
If btClient.Connected = True And isRecieving = True Then
btStream.Write(Data, 0, Data.Length)
btStream.Flush()
End If
End If
Recieving Part:
Code:
While isRecieving = True
If btStream IsNot Nothing And btStream.DataAvailable = True Then
Try
Recieved = btStream.Read(myHeader, 0, myHeader.Length)
If myHeader(0) = HeaderIdentifier And myHeader(1) = OtherModeHeader Then
btStream.Read(myDataSize, 0, 2)
DataLength = BitConverter.ToInt16(myDataSize, 0)
myBuffer = New Byte(DataLength - 1) {}
Recieved = 0
Do Until Recieved = DataLength
If btStream.DataAvailable = True Then
Recieved += btStream.Read(myBuffer, Recieved, DataLength - Recieved)
End If
Loop
ExecuteCommand(myHeader(2), myHeader(3), myBuffer)
Else
Debug.WriteLine("WrongData")
Exit While
End If
Catch ex As Exception
Debug.WriteLine(ex.Message)
If Recieved = 0 Then
Exit While
End If
End Try
End If
End While
If I send the image, without Thread.Sleeps (huighe ones). The recieving stream gets weird. The gets btStream.DataAvailable = False forever. If I remove that ckeck, it hangs at the btStream.Read.
I also tried to fix that with waiting for the answer of the server, but the problem doesn't get solved.
Do you have any idea how to fix that problem?. In that speed the image sending is worthless
SciLor
Hi,
Does anybody know how to pull the time from a server and use that time to update the devices clock?
I want to lock the Clock down on the device so the best way to ensure the time is correct is to sync it with a server.
I'm using VB.net.
Give this a spin.
It sets the get the UTC time, from http://www.timeapi.org/ , but have a look at the site to see what else it can do.
Your device should deal with your timezone offset from UTC automatically.
I used .NET Reflector to translate into VB from C#, hence the odd definition of some variables.
Code:
Public Structure SYSTEMTIME
Public wYear As UInt16
Public wMonth As UInt16
Public wDayOfWeek As UInt16
Public wDay As UInt16
Public wHour As UInt16
Public wMinute As UInt16
Public wSecond As UInt16
Public wMilliseconds As UInt16
End Structure
Declare Function GetSystemTime Lib "CoreDll.dll" _
(ByRef lpSystemTime As SYSTEMTIME) As UInt32
Declare Function SetSystemTime Lib "CoreDll.dll" _
(ByRef lpSystemTime As SYSTEMTIME) As UInt32
Private Shared Sub Main(ByVal args As String())
Dim Buffer As Byte() = New Byte(&H19 - 1) {}
Dim DateItems As String() = New String(8 - 1) {}
Dim Separators As Char() = New Char() { "-"c, "-"c, "T"c, ":"c, ":"c, "+"c, ":"c }
Dim Now As New SYSTEMTIME
Program.GetSystemTime((Now))
Dim ResponseStream As Stream = WebRequest.Create("http://www.timeapi.org/utc/now").GetResponse.GetResponseStream
ResponseStream.Read(Buffer, 0, &H19)
ResponseStream.Close
DateItems = Encoding.UTF8.GetString(Buffer, 0, &H19).Split(Separators)
Now.wYear = Convert.ToUInt16(DateItems(0))
Now.wMonth = Convert.ToUInt16(DateItems(1))
Now.wDay = Convert.ToUInt16(DateItems(2))
Now.wHour = Convert.ToUInt16(DateItems(3))
Now.wMinute = Convert.ToUInt16(DateItems(4))
Now.wSecond = Convert.ToUInt16(DateItems(5))
Now.wMilliseconds = 0
Program.SetSystemTime((Now))
End Sub
The original C# code is here. You will have to convert the C# 'using' statements to VB 'Imports'
Code:
using System;
using System.Net;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
namespace GetTime
{
class Program
{
[DllImport("coredll.dll")]
private extern static void GetSystemTime(ref SYSTEMTIME lpSystemTime);
[DllImport("coredll.dll")]
private extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);
private struct SYSTEMTIME
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
static void Main(string[] args)
{
byte[] Buffer = new byte[25];
string DateString;
string[] DateItems = new string[8];
char[] Separators = new char[7] { '-', '-', 'T', ':', ':', '+', ':' };
SYSTEMTIME Now = new SYSTEMTIME();
GetSystemTime(ref Now);
Stream ResponseStream = WebRequest.Create("http://www.timeapi.org/utc/now").GetResponse().GetResponseStream();
ResponseStream.Read(Buffer, 0, 25);
ResponseStream.Close();
DateString = Encoding.UTF8.GetString(Buffer, 0, 25);
DateItems = DateString.Split(Separators);
Now.wYear = Convert.ToUInt16(DateItems[0]);
Now.wMonth = Convert.ToUInt16(DateItems[1]);
Now.wDay = Convert.ToUInt16(DateItems[2]);
Now.wHour = Convert.ToUInt16(DateItems[3]);
Now.wMinute = Convert.ToUInt16(DateItems[4]);
Now.wSecond = Convert.ToUInt16(DateItems[5]);
Now.wMilliseconds = 0;
SetSystemTime(ref Now);
}
}
}
Here's how it works: The call to the URL returns the date/time as a char buffer.
"2011-12-02T14:56:38+00:00" as an example.
After converting this to a string we convert it into an array of strings in DateItems[] as
2011
12
02
14
56
38
00
00
using Separators[] to split the fields apart.
These are then converted to ushort values in the time structure, before setting the time on the device with it.
Nice code stephj .
Cheers!!!
Thanks for that stephj, will give it a go.
i've tried this and i'm getting a :
The remote server returned an error: (407) Proxy Authentication Required.
any ideas?
I tried the above program on an emulated device connected to the net via its host PC's connection and it worked a treat.
To get through a proxy, you will need to add the following code.
Code:
Program.GetSystemTime((Now))
**************INSERT THIS ****************
Dim Proxy as new WebProxy("http://ProxyServer:80/",true)
proxy.Credentials = CredentialCache.DefaultCredentials
WebRequest.DefaultWebProxy = proxy
**************INSERT ENDS ****************
Dim ResponseStream As Stream = WebRequest.Create("http://www.timeapi.org/utc/now").GetResponse.GetResponseStream
Where the first parameter of the WebProxy constructor is the name of your proxy server, and the port it uses. Here at work, we can get away with just using our proxy server's internal network DNS name of "Internet:8080", to access the outside web through a Microsoft ISA Proxy/Firewall. Note in this case the proxy uses a different port number of 8080 as opposed to the default http port of 80. If yours is not 80 you will have to provide it. You may have to do some groundwork to track down the name of your proxy server, and the port it uses. I would start by looking at the proxy setup in Settings->Connections->'Set up my proxy server' for starters.
CredentialCache.DefaultCredentials, picks up your default login/credentials and passes them to the proxy server. If it works properly, you should go through it, seamlessly.
Good luck!
Hi steph,
i tweaked this slightly and set up a webreference in my program, i then pull the time down from that in the format of "2011-12-12T09:43:14", it then splits it.
The problem i am having is that sometimes it seems to add an hour to the time.
Any ideas?
What time zone is your device operating under?
Start->Settings->[System]->Clock & Alarms->[Time]
What's the zone, and is it Home or Visiting? - I'll see if I can duplicate it.
GMT London and is set as Home.
As a test I set the time on the device to: 01/06/1999 and time 01:00:00. When i run the program the first time i press my 'Update Time' button and it returns 12/12/11 and 12:53:04, so 1 hour ahead. If i press the button again I get the correct time.
I notice on your original post that the time returned had +00:00 on the end but you dont seem to use it when you break the string down, is this not required?
Thanks for the help, much appreciated
At least I can duplicate it, so that is a start. It only seems to throw the hour forward if the date has changed, which explains why the second call to it corrects the time.
If you just knock the time back a couple of hours, a single call of the program sets the correct time.
Interesting. I'll try and get to the bottom of it, might take a day or so, on and off.
Edit: Got it!
The 1st of June 1999 is in BST one hour in front of GMT/UTC. The first call changes the date and time using BST, leaving the time pushed forward one hour. The date is then set to today's date which is in GMT/UTC. The second call sets the time against the GMT Timezone which corrects the time.
Set the date time to 04:00 yesterday and it works fine.
I'll see if we can fix it a bit better. More later.........
Here's the cure: It's C#, I'll leave you to convert it to VB.
The secret is to set the time twice, but stall the thread for ten seconds inbetween. The device will sort itself out in the gap, as various time and date housekeeping tasks are triggered. The second SetTime(), will carry out the final fix of the time before the program finally ends.
This should also work in BST when changing from a GMT/UTC date, and should also work with all global time zones.
Add this:
Code:
using System.Threading;
SetSystemTime(ref Now);
Thread.Sleep(10000);
SetSystemTime(ref Now);
that's great steph, thanks again.
There is a minor problem with the previous code:- If the minute happens to roll over in the 10 seconds while the process is asleep, then the change of minute will be lost.
Here's a better solution. Create a DateTime object in which to store the returned date and time from the WebRequest().
Use it to set the system date/time, and then advance it forward ten seconds.
Set the date/time with it again, after the ten second sleep() has elapsed.
Seems to work O.K. Post bug reports to this thread, if you find it doesn't.
Code:
using System;
using System.Net;
using System.Text;
using System.Threading;
using System.IO;
using System.Runtime.InteropServices;
namespace GetTime
{
class Program
{
[DllImport("coredll.dll")]
private extern static uint SetSystemTime(ref SYSTEMTIME lpSystemTime);
private struct SYSTEMTIME
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
static void Main(string[] args)
{
byte[] Buffer = new byte[25];
string DateString;
string[] DateItems = new string[8];
char[] Separators = new char[7] { '-', '-', 'T', ':', ':', '+', ':' };
SYSTEMTIME Now = new SYSTEMTIME();
Stream ResponseStream = WebRequest.Create("http://www.timeapi.org/utc/now").GetResponse().GetResponseStream();
ResponseStream.Read(Buffer, 0, 25);
ResponseStream.Close();
DateString = Encoding.UTF8.GetString(Buffer, 0, 25);
DateItems = DateString.Split(Separators);
DateTime SaveTime = new DateTime(Convert.ToInt32(DateItems[0]),Convert.ToInt32(DateItems[1]),Convert.ToInt32(DateItems[2]),Convert.ToInt32(DateItems[3]),Convert.ToInt32(DateItems[4]),Convert.ToInt32(DateItems[5]));
Now.wYear = Convert.ToUInt16(SaveTime.Year);
Now.wMonth = Convert.ToUInt16(SaveTime.Month);
Now.wDay = Convert.ToUInt16(SaveTime.Day);
Now.wHour = Convert.ToUInt16(SaveTime.Hour);
Now.wMinute = Convert.ToUInt16(SaveTime.Minute);
Now.wSecond = Convert.ToUInt16(SaveTime.Second);
Now.wMilliseconds = 0;
SetSystemTime(ref Now);
SaveTime.AddSeconds(10);
Thread.Sleep(10000);
Now.wYear = Convert.ToUInt16(SaveTime.Year);
Now.wMonth = Convert.ToUInt16(SaveTime.Month);
Now.wDay = Convert.ToUInt16(SaveTime.Day);
Now.wHour = Convert.ToUInt16(SaveTime.Hour);
Now.wMinute = Convert.ToUInt16(SaveTime.Minute);
Now.wSecond = Convert.ToUInt16(SaveTime.Second);
SetSystemTime(ref Now);
}
}
}
C# .NET CF 2.0 WinMo 5.0 onwards executable is included in the zip file.
It is a console application, so don't expect anything much to happen until the 'hourglass' disappears.
If the first SetSystemTime() ends up changing the date across a Daylight Saving Boundary date, then, during the sleep() period, the device's housekeeping date/time/alarm services will probably retrigger any outstanding task and event reminders for 'today'.
P.S. GetSystemTime() can be dropped it is not required.
works like a charm steph, nice one. thanks.
@stephj, Thanks for the updated code .
Cheers!!!
Seem to be having a problem with this since UK has put the clocks forward an hour, every time I update using this code my device is adding an hour to the time.
The device is an M3 Mobile.
What are the settings on the Start-> Settings->Clock and Alarms->Time[Tab]
It should still have the Home radio button active and the time zone set to GMT London, Dublin. The mobile device should take care of daylight saving itself.
Is your M3 running WinMo 6.1 or 6.5? But I can't see it making much difference.
Works OK on a stock 6.1 Kaiser (Vodafone v1615)
Update: Also seems to work OK on the WM 6.5.3 Professional emulator.
wubbledoos said:
Hi,
Does anybody know how to pull the time from a server and use that time to update the devices clock?
I want to lock the Clock down on the device so the best way to ensure the time is correct is to sync it with a server.
I'm using VB.net.
Click to expand...
Click to collapse
Well on my Kaisers (running either wm 6.1 or 6.5) I use SKTsync to sync my device clock to one of the NIST or SNTP servers. It's freeware and it does it all for you, all you do is run the app. It's soooo simple. I also run an app called CT Scheduler lite. I use it to automatically run SKTsync every night.