00001 /***************************************************************************** 00002 * 00003 * $RCSfile: PortForm_8c-source.html,v $ 00004 * 00005 * GPS4Palm Port Form 00006 * 00007 * Based on the example "GPS" from the book 00008 * "Palm Programming, the Developer's Guide, 2nd edition" 00009 * by O'Reilly. 00010 * (Copyright (c) 1998-2001, Neil Rhodes and Julie McKeehan neil@pobox.com) 00011 * 00012 * This program is Copyright (C) 03/2003 Matthias Prinke 00013 * <matthias.prinke@surfeu.de> and covered by GNU's GPL. 00014 * In particular, this program is free software and comes WITHOUT 00015 * ANY WARRANTY. 00016 * 00017 * $Author: mp $ 00018 * 00019 * $Date: 2007-10-08 20:40:34 $ 00020 * 00021 * $Revision: 1.7.2.1 $ 00022 * 00023 * $Log: PortForm_8c-source.html,v $ 00023 * Revision 1.7.2.1 2007-10-08 20:40:34 mp 00023 * updated for gps4palm V0.9.5 beta 00023 * 00024 * Revision 1.12 2005-04-20 21:13:34 mp 00025 * implemented opening of Bluetooth Virtual Serial Port 00026 * with connecting to known device (address) 00027 * 00028 * Revision 1.11 2005/02/06 14:57:59 mp 00029 * added GPSPortRTSCtrlCheckbox 00030 * 00031 * Revision 1.10 2005/02/05 17:40:15 mp 00032 * Added support for two different ports (Host and GPS), 00033 * storage of selected connection profile (if Connection Manager 00034 * Feature Set is available) or Port Name/Number in Application Preferences. 00035 * 00036 * Revision 1.9 2004/12/18 16:12:52 mp 00037 * fixed serial port re-opening for PDAs with New Serial Manager 00038 * 00039 * Revision 1.8 2004/11/25 17:10:16 mp 00040 * fixed comment 00041 * 00042 * Revision 1.7 2004/11/25 17:02:39 mp 00043 * fixed file header 00044 * 00045 * Revision 1.6 2004/11/24 21:33:37 mp 00046 * moved static function declarations from header to implementation file 00047 * 00048 * Revision 1.5 2004/11/23 18:05:15 mp 00049 * added deallocation of connection profile list 00050 * 00051 * Revision 1.4 2004/04/29 19:22:38 mp 00052 * fixed typo 00053 * 00054 * Revision 1.3 2004/04/29 19:04:40 mp 00055 * added RouteForm, modified for doxygen 00056 * 00057 * Revision 1.2 2004/03/01 17:18:43 mp 00058 * Added some comments, moved global variables from GPS.c, moved creation of list 00059 * from PortFormInit() to PortFormHandleEvent. 00060 * 00061 * Revision 1.1.1.1 2003/07/14 18:59:29 mp 00062 * Imported GPS4Palm to CVS revision control. 00063 * 00064 * 00065 ****************************************************************************/ 00066 #include <PalmOS.h> 00067 #include <BtCommVdrv.h> 00068 #include "ResourceDefines.h" 00069 #include "PortForm.h" 00070 #include "Utils.h" 00071 #include "Serial.h" 00072 #include "gpslib.h" /* GpslibSetSerialPort() */ 00073 #include "common.h" 00074 00075 extern UInt16 gPortID; 00076 extern PrefsType gPrefs; 00077 extern UInt32 gSerialPort; 00078 00079 /* Variables used by Connection Manager */ 00080 extern Char **gProfiles; 00081 extern UInt16 gNumProfiles; 00082 00083 /* Static Functions */ 00084 static void PortFormInit(FormPtr form); 00085 static void PortFormDeinit(); 00086 00087 00088 /***************************************************************************** 00089 * FUNCTION: PortFormInit 00090 * 00091 * DESCRIPTION: Port Form init function 00092 * 00093 * PARAMETERS: form - Form Pointer (unused) 00094 * 00095 * RETURNED: % 00096 * 00097 ****************************************************************************/ 00098 static 00099 void PortFormInit(FormPtr frmP) 00100 { 00101 #pragma unused(form) 00102 // warning-- don't do any drawing in this routine. 00103 // Also, don't call FrmSetFocus from here (it must be called *after* 00104 // FrmDrawForm) 00105 } 00106 00107 00108 /***************************************************************************** 00109 * FUNCTION: PortFormDeinit 00110 * 00111 * DESCRIPTION: Port Form deinit function 00112 * 00113 * Deallocation of memory allocated by CncGetProfileList() 00114 * 00115 * PARAMETERS: % 00116 * 00117 * RETURNED: % 00118 * 00119 ****************************************************************************/ 00120 static 00121 void PortFormDeinit() 00122 { 00123 FreeCncProfileList(); 00124 } 00125 00126 00127 /****************************************************************************/ 00128 /** 00129 * \brief Port Form event handler. 00130 * 00131 * Allows selection of connection profile. Available only 00132 * with New Serial Manager. 00133 * 00134 * \param eventP Pointer to event structure 00135 * 00136 * \return Status flag: event handled 00137 ****************************************************************************/ 00138 Boolean PortFormHandleEvent(EventPtr eventP) 00139 { 00140 Boolean handled; /* flag: event handled */ 00141 FormPtr frmP; /* form ptr */ 00142 ListPtr list; /* list ptr */ 00143 Err err; /* error code */ 00144 UInt16 listSelection; /* list index */ 00145 const UInt16 kMaxVisibleItems = 14; /* max. visible list items */ 00146 UInt16 numVisibleItems = kMaxVisibleItems; 00147 00148 frmP = FrmGetActiveForm(); 00149 handled = false; 00150 00151 switch (eventP->eType) { 00152 case frmOpenEvent: 00153 PortFormInit(frmP); 00154 FrmDrawForm(frmP); 00155 00156 /* Set Auto Power-Off Check Box from Preferences */ 00157 FrmSetControlValue(frmP, 00158 FrmGetObjectIndex(frmP, GPSPortRTSCtrlCheckbox), 00159 gPrefs.serprefs.rts_ctrl); 00160 00161 /* close current port */ 00162 SrmClose(gPortID); 00163 00164 /* create list of available connection profiles */ 00165 err = CncGetProfileList(&gProfiles, &gNumProfiles); 00166 if (gNumProfiles < kMaxVisibleItems) 00167 numVisibleItems = gNumProfiles; 00168 00169 /* configure GPSPortList */ 00170 list = (ListPtr)GetObjectFromForm(frmP, GPSPortList); 00171 LstSetListChoices(list, gProfiles, gNumProfiles); 00172 LstSetHeight(list, numVisibleItems); 00173 00174 if ((gCncManagerFtr) && (CncProfileGetIndex(gPrefs.serprefs.gps_port, 00175 &listSelection) == errNone)) { 00176 LstSetSelection(list, listSelection); 00177 CtlSetLabel(GetObjectFromActiveForm(GPSPortPopupTrigger), 00178 gProfiles[listSelection]); 00179 } else { 00180 LstSetSelection(list, noListSelection); 00181 } 00182 00183 /* configure HostPortList */ 00184 list = (ListPtr)GetObjectFromForm(frmP, HostPortList); 00185 LstSetListChoices(list, gProfiles, gNumProfiles); 00186 LstSetHeight(list, numVisibleItems); 00187 00188 if ((gCncManagerFtr) && (CncProfileGetIndex(gPrefs.serprefs.host_port, 00189 &listSelection) == errNone)) { 00190 LstSetSelection(list, listSelection); 00191 CtlSetLabel(GetObjectFromActiveForm(HostPortPopupTrigger), 00192 gProfiles[listSelection]); 00193 } else { 00194 LstSetSelection(list, noListSelection); 00195 } 00196 00197 handled = true; 00198 break; 00199 00200 case popSelectEvent: 00201 /* update label to selected list item */ 00202 CtlSetLabel(eventP->data.popSelect.controlP, 00203 gProfiles[eventP->data.popSelect.selection]); 00204 handled = true; 00205 break; 00206 00207 case ctlSelectEvent: 00208 if (eventP->data.ctlSelect.controlID == GPSPortUsePortButton) { 00209 Err err; /* error code */ 00210 UInt32 host_port; /* host port */ 00211 UInt32 baud; /* baud rate */ 00212 ListPtr list; /* list prt */ 00213 00214 /* check Host port */ 00215 list = (ListPtr)GetObjectFromActiveForm(HostPortList); 00216 00217 listSelection = LstGetSelection(list); 00218 00219 if (listSelection == noListSelection) { 00220 /* button "OK" pressed, but no profile selected yet */ 00221 FrmAlert(NoProfileSelectedAlert); 00222 break; 00223 } else { 00224 /* get port ID and baud rate from selected profile */ 00225 err = CncGetProfileInfo(gProfiles[listSelection], 00226 &host_port, &baud, 0, 0, 0, 0, 0, 0); 00227 } 00228 00229 if (err == 0) { 00230 err = SrmOpen(host_port, baud, &gPortID); 00231 00232 if (gCncManagerFtr) { 00233 /* save Connection Mannager profile ID */ 00234 CncProfileGetIDFromIndex(listSelection, &gPrefs.serprefs.host_port); 00235 } else { 00236 /* save port name/logical port number and baud rate */ 00237 gPrefs.serprefs.host_port = host_port; 00238 gPrefs.serprefs.host_baud = baud; 00239 } 00240 } 00241 00242 if (err == serErrAlreadyOpen) { 00243 FrmAlert(SerialInUseAlert); 00244 DoClose(gPortID); 00245 } else if (err) { 00246 FrmAlert(CantOpenSerialAlert); 00247 } else { 00248 /* set Serial Port to be used by gpslib */ 00249 GpslibSetSerialPort(host_port); 00250 00251 } 00252 00253 /* close Host port */ 00254 SrmClose(gPortID); 00255 00256 00257 /* check and open GPS port */ 00258 list = (ListPtr)GetObjectFromActiveForm(GPSPortList); 00259 00260 listSelection = LstGetSelection(list); 00261 00262 if (listSelection == noListSelection) { 00263 /* button "OK" pressed, but no profile selected yet */ 00264 FrmAlert(NoProfileSelectedAlert); 00265 break; 00266 } else { 00267 /* get port ID and baud rate from selected profile */ 00268 err = CncGetProfileInfo(gProfiles[listSelection], 00269 &gSerialPort, &baud, 0, 0, 0, 0, 0, 0); 00270 } 00271 00272 if (err == 0) { 00273 if (gSerialPort == sysFileCVirtRfComm) { 00274 /* 00275 * Bluetooth Vitrual Serial Port -- 00276 * Connect to known device (address) 00277 */ 00278 UInt16 btLibRefNum; /* BT Library reference */ 00279 SrmOpenConfigType config; /* port's properties */ 00280 BtVdOpenParams btParams; /* BT parameters */ 00281 int i; /* loop index */ 00282 00283 /* get BT Library reference */ 00284 err = SysLibFind(btLibName, &btLibRefNum); 00285 if (err) break; 00286 00287 /* open Bluetooth Library */ 00288 err = BtLibOpen(btLibRefNum, false /* allowStackToFail */); 00289 if (err) break; 00290 00291 /* 00292 * Discover all available devices, present them 00293 * in the user interface, and allow the user to 00294 * select one of these devices. 00295 * Same as SrmOpen would do, but this provides us 00296 * the device address which allows us to reconnect 00297 * later to the same device automatically! 00298 */ 00299 err = BtLibDiscoverSingleDevice( 00300 btLibRefNum, 00301 NULL, /* *instructionTxt */ 00302 NULL, /* *deviceFilterList */ 00303 0, /* deviceFilterListLen */ 00304 (BtLibDeviceAddressType *)btParams.u.client.remoteDevAddr.address, /* *selectedDeviceP */ 00305 false, /* addressAsName */ 00306 false /* showLastList */ 00307 ); 00308 if (err) break; 00309 00310 /* close Bluetooth Library */ 00311 BtLibClose(btLibRefNum); 00312 00313 config.baud = baud; /* baud rate */ 00314 config.function = 0; /* default */ 00315 config.drvrDataP = (MemPtr)&btParams; 00316 config.drvrDataSize = sizeof(BtVdOpenParams); 00317 btParams.role = btVdClient; /* PDA is client */ 00318 btParams.u.client.method = btVdUseUuidList; /* no particular channel */ 00319 btParams.u.client.u.uuidList.len = 0; /* any service class */ 00320 btParams.authenticate = false; /* no authentification */ 00321 btParams.encrypt = false; /* no encryption */ 00322 00323 /* open BT serial port */ 00324 err = SrmExtOpen(gSerialPort, &config, sizeof(config), &gPortID); 00325 00326 if (!err) { 00327 /* 00328 * if opening succeeded, copy device address 00329 * to Application Preferences 00330 */ 00331 for (i=0; i<btLibDeviceAddressSize; i++) { 00332 gPrefs.serprefs.gps_btaddr[i] = 00333 btParams.u.client.remoteDevAddr.address[i]; 00334 } 00335 } 00336 00337 } else { 00338 /* open non-BT serial port */ 00339 err = SrmOpen(gSerialPort, baud, &gPortID); 00340 } /* if (gSerialPort == sysFileCVirtRfComm) */ 00341 00342 if (gCncManagerFtr) { 00343 /* save Connection Mannager profile ID */ 00344 CncProfileGetIDFromIndex(listSelection, &gPrefs.serprefs.gps_port); 00345 } else { 00346 /* save port name/logical port number and baud rate */ 00347 gPrefs.serprefs.gps_port = gSerialPort; 00348 gPrefs.serprefs.gps_baud = baud; 00349 } 00350 } 00351 00352 if (err == serErrAlreadyOpen) { 00353 FrmAlert(SerialInUseAlert); 00354 DoClose(gPortID); 00355 } else if (err) { 00356 FrmAlert(CantOpenSerialAlert); 00357 } else { 00358 /* port opened successfully */ 00359 err = DoSetReceiveBuffer(gPortID, gSerialBuffer, 00360 sizeof(gSerialBuffer)); 00361 00362 sermux_enable(gPrefs.serprefs.rts_ctrl); 00363 00364 if (gPrefs.serprefs.rts_ctrl) { 00365 sermux_select(false); 00366 } 00367 00368 FrmGotoForm(gPrefs.form); 00369 } 00370 handled = true; 00371 } 00372 00373 if (eventP->data.ctlSelect.controlID == GPSPortRTSCtrlCheckbox) { 00374 gPrefs.serprefs.rts_ctrl = 00375 GetControlValueFromId(GPSPortRTSCtrlCheckbox); 00376 00377 } 00378 break; 00379 00380 case frmCloseEvent: 00381 PortFormDeinit(FrmGetActiveForm()); 00382 handled = false; 00383 break; 00384 00385 } /* switch (eventP->eType) */ 00386 return(handled); 00387 }