GPS4Palm

Source Code Documentation


PortForm.c

Go to the documentation of this file.
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 }

Created: Mon, 08 Oct 2007 22:33:16 +0200
Copyright ©2004 M. Prinke