Garmin Fleet Management Controller  2.19.0
CFileTransferDlg.cpp
Go to the documentation of this file.
1 /*********************************************************************
2 *
3 * MODULE NAME:
4 * CFileTransferDlg.cpp
5 *
6 * Copyright 2008-2011 by Garmin Ltd. or its subsidiaries.
7 *---------------------------------------------------------------------
8 * $NoKeywords$
9 *********************************************************************/
10 #include "stdafx.h"
11 
12 #include <fstream>
13 #include <sstream>
14 #include <string>
15 #include <vector>
16 
17 #include "CFileTransferDlg.h"
19 #include "AobrdEventLogConverter.h"
20 #include "util.h"
21 
22 using namespace std;
23 
24 IMPLEMENT_DYNAMIC( CFileTransferDlg, CDialog )
25 
26 BEGIN_MESSAGE_MAP( CFileTransferDlg, CDialog )
27  ON_EN_CHANGE( IDC_FILE_XFER_EDIT_FILENAME, OnEnChangeFile )
28  ON_EN_CHANGE( IDC_FILE_XFER_EDIT_FILE_VERSION, OnEnChangeFile )
29  ON_BN_CLICKED( IDC_FILE_XFER_BTN_FIND, OnBnClickedFind )
30  ON_BN_CLICKED( IDOK, OnBnClickedOk )
31 END_MESSAGE_MAP()
32 
33 /*--------------------------------------------------------------------
34 LITERAL CONSTANTS
35 --------------------------------------------------------------------*/
36 
39 static CFileTransferDlg::file_type file_types[] =
40 {
41  { FMI_FILE_TYPE_GPI, _T( "GPI" ), NULL, _T( "GPI Files (*.gpi)|*.gpi|" ) }
42  #if( FMI_SUPPORT_A614 )
43  , { FMI_FILE_TYPE_PATH_SPECIFIC_ROUTE, _T( "PSR" ), NULL, _T( "PSR Files (*.*)|*.*|" ) }
44  #endif
45 };
46 
47 //----------------------------------------------------------------------
51 //----------------------------------------------------------------------
53  (
54  CWnd * aParent,
55  FmiApplicationLayer & aCom
56  )
57  : CDialog( IDD_FILE_TRANSFER, aParent )
58  , mCom( aCom )
59  , mFileType( 0 )
60  , mFileTypeIndex( 0 )
61  , mFilePath( _T("") )
62  , mVersion( _T("") )
63 {
64  #if( FMI_SUPPORT_A614 )
65  mOldListItem.setValid( FALSE );
66  #endif
67 }
68 
69 //----------------------------------------------------------------------
71 //----------------------------------------------------------------------
73 {
74 }
75 
76 //----------------------------------------------------------------------
79 //----------------------------------------------------------------------
81  (
82  CDataExchange * aDataExchange
83  )
84 {
85  CDialog::DoDataExchange( aDataExchange );
86 
87  DDX_CBIndex( aDataExchange, IDC_FILE_XFER_CBO_FILE_TYPE, mFileTypeIndex );
88 
89  mFileType = file_types[mFileTypeIndex].index;
90 
91  DDX_Text( aDataExchange, IDC_FILE_XFER_EDIT_FILENAME, mFilePath );
92  DDX_Text( aDataExchange, IDC_FILE_XFER_EDIT_FILE_VERSION, mVersion );
93 }
94 
95 //----------------------------------------------------------------------
101 //----------------------------------------------------------------------
103 {
104  CDialog::OnInitDialog();
105 
106  // Populate file type combobox
107  CComboBox * cbo = (CComboBox *)GetDlgItem( IDC_FILE_XFER_CBO_FILE_TYPE );
108  cbo->ResetContent();
109  for( int i = 0; i < cnt_of_array( file_types ); i++ )
110  {
111  cbo->AddString( file_types[i].text );
112  }
113  cbo->SetCurSel( 0 );
114 
115  return TRUE;
116 } /* OnInitDialog() */
117 
118 //----------------------------------------------------------------------
122 //----------------------------------------------------------------------
124 {
125  BOOL isValid = TRUE;
126 
127  UpdateData( TRUE );
128 
129  if( mFilePath == "" || mVersion == "" )
130  {
131  isValid = FALSE;
132  }
133 
134  if( mVersion.Left( 2 ) == "0x" )
135  {
136  if( mVersion.GetLength() > 34 )
137  isValid = FALSE;
138  }
139  else
140  {
141  if( mVersion.GetLength() > 16 )
142  isValid = FALSE;
143  }
144 
145  if( isValid )
146  {
147  GetDlgItem( IDOK )->EnableWindow( TRUE );
148  }
149  else
150  {
151  GetDlgItem( IDOK )->EnableWindow( FALSE );
152  }
153 }
154 
155 //----------------------------------------------------------------------
159 //----------------------------------------------------------------------
161 {
162  UpdateData();
163 
164  TCHAR workingDirectory[200];
165  // opening a file in another directory changes the current
166  // directory, which will cause problems because the log and data
167  // files are opened relative to the current directory. So, get the
168  // directory now so that it can be restored when the user is done
169  // picking a file.
170  DWORD result = GetCurrentDirectory( 200, workingDirectory );
171  if( result == 0 || result > 200 )
172  {
173  MessageBox( _T("Unable to get current directory"), _T("Severe Error") );
174  OnCancel();
175  return;
176  }
177  CFileDialog dlg
178  (
179  TRUE,
180  file_types[mFileTypeIndex].extension,
181  NULL,
182  OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
183  file_types[mFileTypeIndex].filter
184  );
185  if( dlg.DoModal() == IDOK )
186  {
187  mFilePath = dlg.GetPathName();
188  #if( FMI_SUPPORT_A614 )
189  if( mFileType == FMI_FILE_TYPE_PATH_SPECIFIC_ROUTE )
190  {
191  mVersion = "1"; // Not sure why 1 was chosen but this is
192  } // consistent with what the MapViewer sets
193  #endif
194  UpdateData( FALSE );
195  OnEnChangeFile();
196  }
197  if( !SetCurrentDirectory( workingDirectory ) )
198  {
199  MessageBox( _T("Unable to set current directory"), _T("Severe Error") );
200  OnCancel();
201  return;
202  }
203 } /* OnBnClickedFind() */
204 
205 //----------------------------------------------------------------------
213 //----------------------------------------------------------------------
215 {
216  UpdateData( TRUE );
217  char file[200];
218 
219  char versionString[35];
220  uint8 version[16];
221  uint8 versionLength;
222 
223  memset( version, 0, sizeof( version ) );
224  WideCharToMultiByte( mCom.mClientCodepage, 0, mVersion, -1, versionString, 34, NULL, NULL );
225  versionString[34] = '\0';
226 
227  if( strncmp( versionString, "0x", 2 ) == 0 )
228  {
229  versionLength = (uint8)UTIL_hex_to_uint8( versionString + 2, version, 16 );
230  }
231  else
232  {
233  versionLength = (uint8)minval( 16, strlen( versionString ) );
234  memmove( version, versionString, versionLength );
235  }
236 
237  WideCharToMultiByte( CP_ACP, 0, mFilePath.GetBuffer(), -1, file, 200, NULL, NULL );
238  file[199] = '\0';
239  fstream open_file( file, ios_base::binary | ios_base::in );
240  if( open_file.good() )
241  {
242  open_file.close();
243 
244  mCom.sendFile( file, versionLength, version, (uint8)mFileType );
245 
246  #if( FMI_SUPPORT_A614 )
247  uint32 itemId = INVALID32;
248  if( mFileType == FMI_FILE_TYPE_PATH_SPECIFIC_ROUTE )
249  {
250  //add this to the Stops list now so that the UI can receive status updates, as opposed
251  //to adding it after the transfer progress dialog returns from modal, which may happen
252  //after the device reports a status update of the new stop it receives to the Stops dialog
253  AddPSRtoStopList( file, itemId );
254  }
255  #endif
256 
257  CFileTransferProgressDlg sending_dlg( this, mCom );
258  UINT sendResult = sending_dlg.DoModal();
259 
260  #if( FMI_SUPPORT_A614 )
261  // If the transfer failed, remove the invalid stop from the list
262  // or replace it with the preexisting stop.
263  if( IDOK != sendResult )
264  {
265  if( mOldListItem.isValid() )
266  mCom.mA603Stops.put( mOldListItem );
267  else
268  mCom.mA603Stops.remove( itemId );
269  }
270  #endif
271  }
272  else
273  {
274  mFilePath += _T(" could not be opened ");
275  MessageBox( mFilePath, _T("Error!") );
276  }
277  open_file.close();
278  OnOK();
279 } /* OnBnClickedOk */
280 
281 #if( FMI_SUPPORT_A614 )
282 //----------------------------------------------------------------------
285 //----------------------------------------------------------------------
287 {
288  ifstream open_file( file, ios_base::binary | ios_base::in | ios_base::ate );
289  if( open_file.good() )
290  {
291  const short buffSize = 200;
292  char buffer[buffSize];
293  memset( buffer, 0, buffSize );
294  CString stopText;
295  // check file size
296  int fSize = open_file.tellg();
297  // if the file is large enough to contain the header,
298  // grab the information we need for the stop list.
299  if( fSize > 14 )
300  {
301  // Advance file pointer to the beginning of Unique ID
302  // PSR+ header (4 bytes)
303  // File format (2 bytes)
304  // Timestamp (4 bytes)
305  // Unique ID (4 bytes)
306  // Stop Text (Max 200 bytes)
307  open_file.seekg( 0, ios::beg );
308  open_file.seekg( 10 );
309  open_file.read( reinterpret_cast<char*>(&itemId), sizeof(uint32) );
310  open_file.read( buffer, buffSize );
311  // assign the stop text string if it is null terminated
312  for( int i = 0; i < buffSize; i++ )
313  {
314  if( buffer[i] == NULL )
315  {
316  TCHAR tcharName[200];
317  MultiByteToWideChar( CP_UTF8, 0, buffer, -1, tcharName, 200 );
318  stopText.SetString( tcharName );
319  break;
320  }
321  }
322  if( itemId != INVALID32 )
323  {
324  // Add the stop to the list
325  StopListItem& stopListItem = mCom.mA603Stops.get( itemId );
326  // If we are replacing a current ID, save it in case the transfer fails
327  if( stopListItem.isValid() )
328  mOldListItem = stopListItem;
329  else
330  mOldListItem.setValid( FALSE );
331  stopListItem.setCurrentName( stopText );
332  stopListItem.setStopStatus( STOP_STATUS_UNREAD );
333  stopListItem.setValid();
334  mCom.mA603Stops.put( stopListItem );
335  }
336  }
337  }
338  open_file.close();
339 }
340 #endif
BOOL isValid() const
Check whether this item is valid.
Modal dialog displaying the status of the file transfer.
#define IDD_FILE_TRANSFER
Definition: resource.h:30
CFileTransferDlg(CWnd *aParent, FmiApplicationLayer &aCom)
Constructor.
#define IDC_FILE_XFER_BTN_FIND
Definition: resource.h:237
afx_msg void OnEnChangeFile()
Edit Change handler for all text boxes.
STL namespace.
afx_msg void OnBnClickedFind()
Click handler for Find (file to send) button.
virtual void DoDataExchange(CDataExchange *aDataExchange)
Perform dialog data exchange and validation.
#define cnt_of_array(_a)
The number of elements in _a.
Definition: util_macros.h:90
#define FALSE
Definition: garmin_types.h:46
void setValid(BOOL aValid=TRUE)
Set this item as valid.
Data structure to hold details of an A603 stop that the server needs to keep.
Definition: StopListItem.h:21
#define TRUE
Definition: garmin_types.h:45
#define INVALID32
Placeholder for an invalid 32-bit value.
Definition: fmi.h:139
void setCurrentName(CString aName)
Set the current name of the stop.
#define minval(_x, _y)
The smaller of _x and _y.
Definition: util_macros.h:95
uint16 UTIL_hex_to_uint8(const char *aHexString, uint8 *aBinaryData, uint16 aMaxBytes)
Convert a hexadecimal ASCII string to an array of uint8.
Definition: util.cpp:323
Serial communication controller for Garmin and FMI packets.
#define IDC_FILE_XFER_EDIT_FILE_VERSION
Definition: resource.h:238
BOOL OnInitDialog()
Initialize the dialog.
#define IDC_FILE_XFER_EDIT_FILENAME
Definition: resource.h:239
Modal dialog allowing the user to select a file to transfer to the client.
void setStopStatus(stop_status_status_type aStatus)
Set the stop status.
unsigned char uint8
8-bit unsigned integer
Definition: garmin_types.h:62
#define IDC_FILE_XFER_CBO_FILE_TYPE
Definition: resource.h:405
virtual ~CFileTransferDlg()
Destructor.
unsigned long int uint32
32-bit unsigned integer
Definition: garmin_types.h:66
void AddPSRtoStopList(char *file, uint32 &itemId)
Adds the transferred PSR to the stop list.
afx_msg void OnBnClickedOk()
Click handler for OK button.
static CFileTransferDlg::file_type file_types[]
File types that the client accepts.