// Text of project Brand X Modem written on 11/22/95 at 7:47 PM
// Beginning of text file Project Data
/*
**      Modem Setup Installer v2.0
**
**		This project creates modem setups for use with the
**		2.0 or later Newton Operating System ONLY.
**
**		Newton Developer Technical Support Sample Code
**      Copyright © 1995 by Apple Computer, Inc.  All rights reserved.
**
**		To build your own modem setup...
**		1)  Copy the entire project and rename the Project File appropriately.
**		2)  Change the Package Name in Project Settings.
**		3)  Edit the constants in Project Data for your modem.
**		4)  Recompile and download.
*/

// ==================== MODEM GENERAL INFO ====================

constant kModemName := "Brand X Modem";
	// type:	string
	// range:	length > 0
	//
	// This is the name of the modem setup as seen in modem prefs.

constant kVersion := 1;
	// type:	integer
	// range:	positive 30-bit integer value
	//
	// Use ONLY integers for version numbers!!!  This number is
	// compared to the currently installed modem setup version
	// number (if any) to determine the appropriate wording for
	// a user confirmation slip (see :MInstall() for more info).

constant kOrganization := "Apple Computer, Inc.";
	// type:	string
	// range:	length > 0
	//
	// Change this accordingly (for informational use).

// ===================== LOCALIZATION INFO ====================
// To build localized modem setups, simply duplicate the
// frame "Custom" below, name it according to the language you
// are localizing to, and enter that name in the Language box
// in Project Settings.  When you compile, the LocObj function
// will use the appropriate strings according to the language
// you have specified in Project Settings.

SetLocalizationFrame({
		Custom:		{	fNotifyIncompatible:	"The \"" & kModemName & "\" modem setup is not compatible with this unit.",
						fConfirmNewer:			"You are about to install a NEWER version of the \"" & kModemName & "\" modem setup.  Continue?",
						fConfirmOlder:			"You are about to install an OLDER version of the \"" & kModemName & "\" modem setup.  Continue?",
						fConfirmSame:			"The \"" & kModemName & "\" modem setup is already installed.  Reinstall?",
					},
	});

// =================== MODEM PREFS ENTRIES ====================

constant kIdModem := true;
	// type:	boolean
	// range:	nil, true
	// default:	true
	//
	// If true, the Newton Modem Tool will execute an ID sequence
	// in an attempt to identify the modem which is connected.
	// If the modem is identified, the NMT configures the active
	// modem profile accordingly.  The ID sequence is run when
	// the Bind call is made to the NMT.  NOTE: the modem is reset
	// during the ID sequence using the AT&F command.
	// If nil, the NMT skips the ID sequence and configures the
	// active profile to the default.  Modem is not reset.

constant kUseHardwareCD := true;
	// type:	boolean
	// range:	nil, true
	// default:	true
	//
	// If true, the NMT will sense the CD line for determining loss
	// of carrier.  External modems must use a cable which connects the
	// CD RS-232 signal to the Newtons GPi serial pin (pin 7 on MP’s).
	// If nil, CD is ignored.

constant kUseConfigString := true;
	// type:	boolean
	// range:	nil, true
	// default:	true
	//
	// If true, before initiating a connection, send the current
	// configuration string to the modem (as determined by active
	// modem profile and the connection type).
	// If nil, no configuration string is sent.
	
constant kUseDialOptions := true;
	// type:	boolean
	// range:	nil, true
	// default:	true
	//
	// If true, before initiating a connection, after configString
	// is sent to modem, set modem dialing configuration according
	// to current option settings.
	// If nil, dial configuration string is not sent to modem.
	// Default dial config string:  "ATM1L2X4S7=060S8=001S6=003\n"

constant kHangUpAtDisconnect := true;
	// type:	boolean
	// range:	nil, true
	// default:	true
	//
	// If true, when the NMT disconnects, hang up the modem.
	// If nil, when the NMT disconnects, no commands are sent to the modem.


// =================== MODEM PROFILE ENTRIES ==================

constant kSupportsEC := nil;
	// type:	boolean
	// range:	nil, true
	// default:	nil
	//
	// If true, indicates modem supports built in error correction,
	// and the profile contains configuration strings for error correction.

constant kSupportsLCS := nil;
	// type:	boolean
	// range:	nil, true
	// default:	nil
	//
	// If true, indicates modem supports Line Current Sense.  LCS
	// is used for determining when a user has lifted the phone
	// handset off hook.  Applications take advantage of this
	// feature by allowing the modem to determine when it
	// should release the line for a voice call.
	// If nil, the modem does not support LCS.  In this case,
	// an application can use a dialog box and user interaction to
	// determine when to tell the modem to release the line (ATH).

constant kDirectConnectOnly := true;
	// type:	boolean
	// range:	nil, true
	// default:	true
	//
	// If true, indicates modem only supports direct connect mode
	// and can't speed buffer.  In this case, for data connections,
	// the DTE speed must be adjusted to the modem speed after the
	// carrier is established. 
	// If nil, indicates the modem supports speed buffering, and
	// use of CTS flow control.
	// NOTE:  For FAX connections, flow control is required! 
	// The string kConfigStrNoEC is used to configure the modem
	// for fax connections.  If kDirectConnectOnly is true,
	// kConfigStrNoEC should enable software flow control.

constant kConnectSpeeds := '[300, 1200, 2400, 4800, 7200, 9600, 12000, 14400];
	// type:	constant array of length > 0
	// range:	each element a positive 30-bit integer value
	// default:	'[300, 1200, 2400, 4800, 7200, 9600, 12000, 14400]
	//
	// Indicates speeds at which the modem can connect.  The value
	// of kConnectSpeeds does NOT effect how the modem is
	// configured.  The intention is to allow the application to
	// read this value to determine the modem's capabilities.

constant kConfigSpeed := 19200;
	// type:	integer
	// unit:	bps
	// range:	positive 30-bit integer value
	// default:	19200
	//
	// (bps) speed at which to configure the modem

constant kCommandTimeout := 2000;
	// type:	integer
	// unit:	milliseconds
	// range:	positive 30-bit integer value
	// default:	2000
	//
	// (ms) how long we'll wait for modem response to a command before timing out

constant kMaxCharsPerLine := 40;
	// type:	integer
	// range:	positive 30-bit integer value
	// default:	40
	//
	// Indicates maximum number of characters per command line, 
	// NOT COUNTING "AT" and <cr>!  The modem controller uses this
	// number to ensure the dial string does not exceed the modem's
	// capability.  If the number of characters in the dial string
	// exceeds this number, the dial string will be split into
	// multiple commands, with ; appended to the intermediate
	// dial string commands.

constant kInterCmdDelay := 25;
	// type:	integer
	// unit:	milliseconds
	// range:	positive 30-bit integer value
	// default:	25
	//
	// Indicates minimum amount of (ms) delay required between
	// modem commands.  This is the time from the last response
	// received to the next command sent.

constant kModemIDStr := nil;
	// type:	string
	// range:	nil, length > 0
	// default:	nil
	//
	// Modem response to the ATI4 command.  If the modem responds
	// with more than one result string, kModemIDStr should 
	// contain only one result string.

constant kConfigStrNoEC := "ATE0&C1S12=12W2&K3&Q6\n";
	// type:	string
	// range:	nil, length > 0
	// default:	"ATE0&C1S12=12W2&K3&Q6\n"
	//
	// Modem command string used to configure modem for a non-
	// error corrected connection.  Uses speed buffering.  This
	// string is used for FAX connections.

 constant kConfigStrECOnly := nil;
	// type:	string
	// range:	nil, length > 0
	// default:	nil
	//
	// Modem command string used to configure the modem for an
	// error corrected connection.  Uses speed buffering.  This
	// string should be nil for modems that do not support error
	// correction.

 constant kConfigStrECAndFallback := nil;
	// type:	string
	// range:	nil, length > 0
	// default:	nil
	//
	// Modem command string used to negotiate for error correction.
	// If error correction negotiation fails, the modem will fall
	// back to a non-error corrected connection.  Uses speed
	// buffering.  This string should be nil for modems that
	// do not support error correction.

constant kConfigStrDirectConnect := "ATE0&C1S12=12W2&K0&Q0\n";
	// type:	string
	// range:	nil, length > 0
	// default:	"ATE0&C1S12=12W2&K0&Q0\n"
	//
	// Modem command string used to configure the modem to connect
	// in direct mode.  Speed buffering is disabled.  After
	// connecting in data mode, the DTE speed will be adjusted to
	// match the modem speed. 


// ==================== FAX PROFILE ENTRIES ===================

constant kServiceClass := kModemFaxClass0 + kModemFaxClass1 + kModemFaxClass2 + 0x00000008;
	// type:	integer
	// range:	positive 30-bit integer value
	// default:	kModemFaxClass0 + kModemFaxClass1 + kModemFaxClass2 + kModemFaxClass2_0
	//
	// Defines the fax service classes to consider when initiating the fax tool. 


constant kTransmitDataMod :=	kV17st_14Mod + kV17_14Mod + kV17st_12Mod + kV17_12Mod +
								kV17st_96Mod + kV17_96Mod + kV17st_72Mod + kV17_72Mod +
								kV29_96Mod   + kV29_72Mod + kV27Ter48Mod + kV27Ter24Mod;
	// type:	integer
	// range:	positive 30-bit integer value
	// default:	kV17st_14Mod + kV17_14Mod + kV17st_12Mod + kV17_12Mod +
	//			kV17st_96Mod + kV17_96Mod + kV17st_72Mod + kV17_72Mod +
	//			kV29_96Mod   + kV29_72Mod + kV27Ter48Mod + kV27Ter24Mod
	//
	// Defines the fax send speeds we are willing to negotiate. 

constant kReceiveDataMod := kV17st_14Mod + kV17_14Mod + kV17st_12Mod + kV17_12Mod +
							kV17st_96Mod + kV17_96Mod + kV17st_72Mod + kV17_72Mod +
							kV29_96Mod   + kV29_72Mod + kV27Ter48Mod + kV27Ter24Mod;
	// type:	integer
	// range:	positive 30-bit integer value
	// default:	kV17st_14Mod + kV17_14Mod + kV17st_12Mod + kV17_12Mod +
	//			kV17st_96Mod + kV17_96Mod + kV17st_72Mod + kV17_72Mod +
	//			kV29_96Mod   + kV29_72Mod + kV27Ter48Mod + kV27Ter24Mod
	//
	// Defines the fax receive speeds we are willing to negotiate. 

constant kTransmitHDLCDataMod := kV21Ch2Mod;
	// type:	integer
	// range:	positive 30-bit integer value
	// default:	kV21Ch2Mod
	//
	// Defines the speed at which the send HDLC frames are transmitted.
	// This value will probably never be overridden. 

constant kReceiveHDLCDataMod := kV21Ch2Mod;
	// type:	integer
	// range:	positive 30-bit integer value
	// default:	kV21Ch2Mod
	//
	// Defines the speed at which the receive HDLC frames are transmitted.
	// This value will probably never be overridden. 

// ============================================================
// End of text file Project Data
// Beginning of text file Installer
// Copyright © 1995 by Apple Computer, Inc.  All rights reserved.

DefConst('kRemoveThisPackageFunc, func(objRef) RemovePackage(ObjectPkgRef(objRef)));

partData := { fInstaller:
{
	fModemSetup:
		{	modemName:		kModemName,
			version:		kVersion,
			organization:	kOrganization,
			
			modemPrefs: 
			{
				idModem:				kIdModem,
				useHardwareCD:			kuseHardwareCD,
				useConfigString:		kuseConfigString,
				useDialOptions:			kuseDialOptions,
				hangUpAtDisconnect:		khangUpAtDisconnect,
			},
			
			modemProfile: 
			{
				supportsEC:				ksupportsEC,
				supportsLCS:			ksupportsLCS,
				directConnectOnly:		kdirectConnectOnly,
				connectSpeeds:			kconnectSpeeds,
				configSpeed:			kconfigSpeed,
				commandTimeout:			kcommandTimeout,
				maxCharsPerLine:		kmaxCharsPerLine,
				interCmdDelay:			kinterCmdDelay,
				modemIdStr:				kModemIdStr,
				configStrNoEC:			kconfigStrNoEC,
				configStrECOnly:		kconfigStrECOnly,
				configStrECAndFallback:	kconfigStrECAndFallback,
				configStrDirectConnect:	kconfigStrDirectConnect,
			},
			
			faxProfile:
			{
				serviceClass:			kServiceClass,
				transmitDataMod:		kTransmitDataMod,
				receiveDataMod:			kReceiveDataMod,
				transmitHDLCDataMod:	kTransmitHDLCDataMod,
				receiveHDLCDataMod:		kReceiveHDLCDataMod,
			},
		},
	
	
	MInstall:
		func()
		begin
			// This function is called from the package's InstallScript and executes from pseudo-ROM.
			// We need a RAM-based frame to hold temporary variables during installation.
			
			local RamBasedSelf :=
				{	_proto:			self,
					fEntry:			GetModemSetup(kModemName),
			 	};
			
			if RamBasedSelf.fEntry <> nil then
			 	begin
			 		// if one is installed, check the setup version number
					local versionInstalled := RamBasedSelf.fEntry.version;
					local message;
					
					if kVersion <> versionInstalled then 
						if kVersion > versionInstalled then
							message := LocObj("You are about to install a NEWER version of the \"" & kModemName & "\" modem setup.  Continue?", 'fConfirmNewer);
						else
							message := LocObj("You are about to install an OLDER version of the \"" & kModemName & "\" modem setup.  Continue?", 'fConfirmOlder);
					else
						message := LocObj("The \"" & kModemName & "\" modem setup is already installed.  Reinstall?", 'fConfirmSame);
					
					GetRoot():Confirm(kAppName, message, RamBasedSelf, 'MInstallConfirmScript);
				end;
			
			else	// there is no modem setup currently installed for this modem, so add one
		 		RamBasedSelf:MInstallConfirmScript(true);
		end,
	
	
	MInstallConfirmScript:
		func(confirmed)			// self is the RamBasedSelf frame
		begin
			if confirmed then
				begin
					RemoveModemSetup(kModemName);		// remove the old one
					AddModemSetup(Clone(fModemSetup));	// add the new one
				end;
			
			AddDeferredCall(EnsureInternal(kRemoveThisPackageFunc), [kModemName]);
		end,
}, };


SetPartFrameSlot(	'DoNotInstall,
					func()
					begin
						if not GlobalFnExists('AddModemSetup)
						or not GlobalFnExists('RemoveModemSetup)
						or not GlobalFnExists('GetModemSetup) then
							begin
								GetRoot():Notify(kNotifyAlert, kAppName, LocObj("The \"" & kModemName & "\" modem setup is not compatible with this unit.", 'fNotifyIncompatible));
								return true;
							end;
						
						nil;
					end	);

InstallScript	:=	func(partFrame, removeFrame)
					AddDeferredCall(	func(base) base:MInstall(),
										[partFrame.partData.fInstaller]	);

RemoveScript	:=	nil;
// End of text file Installer



