#include "stdafx.h" #include "debug.h" #include "gsmdevice.h" typedef void (*PFVOID)(); typedef HRESULT (*PFRIL_Initialize)(DWORD dwIndex, PFVOID pfnResult, PFVOID pfnNotify, DWORD dwNotificationClasses, DWORD dwParam, HANDLE *hRil); typedef HRESULT (*PFRIL_Deinitialize)(HANDLE hRil); typedef HRESULT (*PFRIL_GetRegistrationStatus)(HANDLE hRil); typedef HRESULT (*PFRIL_GetCellTowerInfo)(HANDLE hRil); typedef HRESULT (*PFRIL_DevSpecific)(HANDLE hRil, BYTE*buf, int size); PFRIL_Deinitialize RIL_Deinitialize; PFRIL_Initialize RIL_Initialize; PFRIL_GetRegistrationStatus RIL_GetRegistrationStatus; PFRIL_GetCellTowerInfo RIL_GetCellTowerInfo; PFRIL_DevSpecific RIL_DevSpecific; class RilLib { public: RilLib() { m_hRilDll= LoadLibrary(L"ril.dll"); RIL_Initialize= (PFRIL_Initialize)GetProcAddress(m_hRilDll, L"RIL_Initialize"); RIL_Deinitialize= (PFRIL_Deinitialize)GetProcAddress(m_hRilDll, L"RIL_Deinitialize"); RIL_GetRegistrationStatus= (PFRIL_GetRegistrationStatus)GetProcAddress(m_hRilDll, L"RIL_GetRegistrationStatus"); RIL_GetCellTowerInfo= (PFRIL_GetCellTowerInfo)GetProcAddress(m_hRilDll, L"RIL_GetCellTowerInfo"); RIL_DevSpecific= (PFRIL_DevSpecific)GetProcAddress(m_hRilDll, L"RIL_DevSpecific"); } ~RilLib() { FreeLibrary(m_hRilDll); RIL_Initialize= NULL; RIL_Deinitialize= NULL; RIL_GetRegistrationStatus= NULL; RIL_GetCellTowerInfo= NULL; RIL_DevSpecific= NULL; } private: HMODULE m_hRilDll; } g_rillib; GsmDevice::GsmDevice() { m_hRilDev= NULL; m_hRil= NULL; m_hCom= NULL; } GsmDevice::~GsmDevice() { close(); } bool GsmDevice::open() { m_hCom= CreateFile(L"COM2:",GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0); if (m_hCom==NULL || m_hCom==INVALID_HANDLE_VALUE) { error("CreateFile('COM2:')"); m_hCom= NULL; return false; } DCB dcb; if (!GetCommState(m_hCom, &dcb)) { error("GetCommState"); return false; } dcb.BaudRate= CBR_115200; dcb.ByteSize= 8; dcb.fParity= false; dcb.StopBits= ONESTOPBIT; if (!SetCommState(m_hCom, &dcb)) { error("SetCommState"); return false; } if (!EscapeCommFunction(m_hCom, SETDTR)) { error("SETDTR"); return false; } if (!EscapeCommFunction(m_hCom, SETRTS)) { error("SETRTS"); return false; } COMMTIMEOUTS to; if (!GetCommTimeouts(m_hCom, &to)) { error("GetCommTimeouts"); return false; } to.ReadIntervalTimeout= 0; to.ReadTotalTimeoutConstant= 200; to.ReadTotalTimeoutMultiplier= 0; to.WriteTotalTimeoutConstant= 20000; to.WriteTotalTimeoutMultiplier= 0; if (!SetCommTimeouts(m_hCom, &to)) { error("SetCommTimeouts"); return false; } if (!SetCommMask(m_hCom, EV_RXCHAR)) { error("SetCommMask"); return false; } if (!RIL_Initialize(1, NULL, NULL, 0x00040000L, NULL, &m_hRil)) { error("RIL_Initialize"); return false; } debug("status=%08lx\n", RIL_GetRegistrationStatus(m_hRil)); m_hRilDev= CreateFile(L"RIL1:",GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM,0); if (m_hRilDev==NULL || m_hRilDev==INVALID_HANDLE_VALUE) { error("CreateFile('RIL1:')"); return false; } DWORD nReturned; DWORD rildevresult; if (!DeviceIoControl(m_hRilDev, 0x03000314L,0,0, &rildevresult, sizeof(DWORD), &nReturned,0)) { error("DeviceIoControl ril 0x03000314L"); return false; } debug("ril ioctl 0xc2: %08lx\n", rildevresult); BYTE comdevcmd[2]= {0x84, 0x00}; if (!DeviceIoControl (m_hCom,0xAAAA5679L, comdevcmd, sizeof(comdevcmd),0,0,0,0)) { error("DeviceIoControl com 0xAAAA5679L"); return false; } return true; } bool GsmDevice::close() { if (m_hRilDev!=NULL) { DWORD nReturned; DWORD rildevresult; if (!DeviceIoControl(m_hRilDev, 0x03000318L,0,0, &rildevresult, sizeof(DWORD), &nReturned,0)) { error("DeviceIoControl ril 0x03000318L"); } debug("ril ioctl 0xc6: %08lx\n", rildevresult); CloseHandle(m_hRilDev); m_hRilDev= NULL; } if (m_hRil!=NULL) { debug("status=%d\n", RIL_GetRegistrationStatus(m_hRil)); RIL_Deinitialize(m_hRil); m_hRil= NULL; } if (m_hCom!=NULL) { CloseHandle(m_hCom); m_hCom= NULL; } return true; } bool GsmDevice::SendData(BYTE *buf, DWORD len) { DWORD nWritten; if (!WriteFile(m_hCom, buf, len, &nWritten, NULL)) { error("senddata"); return false; } if (nWritten!=len) debug("WARNING: not all data sent!!\n"); return true; } bool GsmDevice::SendByte(BYTE c) { return SendData(&c, sizeof(BYTE)); } #define VSP_END_OF_MESSAGE 0x02 bool GsmDevice::SendEndOfMessage() { return SendByte(VSP_END_OF_MESSAGE); } bool GsmDevice::ReceiveData(BYTE *buf, int maxlen, DWORD *pnRead) { DWORD event; if (!WaitCommEvent(m_hCom, &event, NULL)) { error("WaitCommEvent"); return false; } *pnRead= 0; while (maxlen) { DWORD nRead; if (!ReadFile(m_hCom, buf, maxlen, &nRead, NULL)) { error("ReadFile"); return false; } if (nRead==0) break; buf += nRead; maxlen -= nRead; *pnRead += nRead; } return true; } /* bool GsmDevice::vspsend(int channel, CString& str) { int datalen= str.GetLength(); BYTE *data= new BYTE[datalen+1]; _snprintf((char*)data, datalen, "%ls", str.GetBuffer(0)); bool bRes= SendEndOfMessage() && SendByte(channel) && SendData(data, datalen) && SendEndOfMessage(); delete data; return bRes; } bool GsmDevice::vspreceive(int channel, CString& str) { BYTE data[512+1]; DWORD nRead; if (!ReceiveData(data, 512, &nRead)) return false; data[nRead]= 0; int i=0; while (i<512) { if (data[i]==channel) break; i++; } if (i==512) return false; int j=i; while (j<512) { if (data[j]==VSP_END_OF_MESSAGE) break; j++; } if (j==512) debug("warning: no end of message\n"); data[j]= 0; str.Format(L"%hs", data+i); return true; } */ bool GsmDevice::send(CString& str) { int datalen= str.GetLength(); BYTE *data= new BYTE[datalen+1]; _snprintf((char*)data, datalen, "%ls", str.GetBuffer(0)); bool bRes= SendData(data, datalen); delete data; return bRes; } bool GsmDevice::receive(CString& str) { BYTE data[512+1]; DWORD nRead; if (!ReceiveData(data, 512, &nRead)) return false; data[nRead]= 0; str.Format(L"%hs", data); return true; } void GsmDevice::flush() { PurgeComm(m_hCom, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_RXABORT | PURGE_TXABORT); }