Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
BSDLLCTest.c
/* |
File: BSDLLCTest.c |
Contains: Simple app write or receive 8022 Ethernet packets using a raw mode socket |
Copyright: Copyright (c) 1998-2003 by Apple Computer, Inc., All Rights Reserved. |
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. |
("Apple") in consideration of your agreement to the following terms, and your |
use, installation, modification or redistribution of this Apple software |
constitutes acceptance of these terms. If you do not agree with these terms, |
please do not use, install, modify or redistribute this Apple software. |
In consideration of your agreement to abide by the following terms, and subject |
to these terms, Apple grants you a personal, non-exclusive license, under AppleĆs |
copyrights in this original Apple software (the "Apple Software"), to use, |
reproduce, modify and redistribute the Apple Software, with or without |
modifications, in source and/or binary forms; provided that if you redistribute |
the Apple Software in its entirety and without modifications, you must retain |
this notice and the following text and disclaimers in all such redistributions of |
the Apple Software. Neither the name, trademarks, service marks or logos of |
Apple Computer, Inc. may be used to endorse or promote products derived from the |
Apple Software without specific prior written permission from Apple. Except as |
expressly stated in this notice, no other rights or licenses, express or implied, |
are granted by Apple herein, including but not limited to any patent rights that |
may be infringed by your derivative works or by other works in which the Apple |
Software may be incorporated. |
The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO |
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED |
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN |
COMBINATION WITH YOUR PRODUCTS. |
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION |
OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT |
(INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN |
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
* |
*/ |
#include "BSDLLCTest.h" |
#include "GetEthernetAddrSample.h" |
#include "EthernetSocketStuff.h" |
#include "MoreUNIX.h" |
enum { |
kDestAddressField = 1, |
kDSAPField = 2, |
kSNAPField = 3, |
kNumPacketsField = 4, |
kSendTimeField = 5, |
kTransferRateField = 6, |
kNumPacketsReceivedField = 7, |
kNumPacketsInOrderField = 8, |
kNumPacketsOutOfOrderField = 9, |
kLastPacketReceivedField = 10, |
kDoTestButton = 11, |
kSendReceiveButton = 12, |
kSNAPLabel = 13, |
kSourceAddressField = 14, |
kDestAddressIsMCast = 15, |
kEnetPopupButton = 16, |
kCancelTestButton = 17, |
kAboutAppNameText = 18, |
kAboutVersionText = 19, |
kQuitButton = 20, |
kLastItem |
}; |
#define kMaxInputSize 32 |
//----------------------------------------------------------------------------------------- |
// Globals |
//----------------------------------------------------------------------------------------- |
IBNibRef gNibRef; |
WindowRef gMainWindow; |
WindowRef gAboutWindow; |
EventLoopRef gMainLoop; |
EventLoopTimerUPP gTimerUPP; |
EventLoopTimerRef gTimerRef; |
EventHandlerUPP gMyDoTestButtonInterceptorUPP; |
EventHandlerUPP gMyDoCancelTestButtonInterceptorUPP; |
EventHandlerUPP gMySendRcvButtonInterceptorUPP; |
EventHandlerUPP gMyAppCommandInterceptorUPP; |
EventHandlerUPP gMyEnetPopupCommandInterceptorUPP; |
EventHandlerUPP gMyDestAddrIsMCastInterceptorUPP; |
EnetData gedata[kMaxEnetEntries]; |
EnetTestData gTestData; |
EnetTestData *gEnetTestData = &gTestData; |
UInt32 gNumEnetEntries = kMaxEnetEntries; |
UInt32 gCurrPopupEntry = 1; |
UInt32 gVerMacOS; |
MACAddress gDestAddr = {MCASTADDR0, MCASTADDR1, MCASTADDR2, MCASTADDR3, MCASTADDR4, MCASTADDR5}; |
MACAddress gBroadcastAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
UInt16 gSAPAddr = DEFAULTSAP; |
UInt8 gSNAPAddr[5] = {MYSNAP0, MYSNAP1, MYSNAP2, MYSNAP3, MYSNAP4}; |
UInt32 gSendRcvState = kSendTest; // indicates the current state of the test |
UInt32 gNumPacketsToHandle = DEFAULT_NUM_PACKETS_TO_SEND; |
UInt32 gFlags; |
int gshmid; |
Boolean gDestAddrIsMCast; |
Boolean gDone; |
Boolean gAbort = FALSE; |
//----------------------------------------------------------------------------------------- |
// Prototypes |
//----------------------------------------------------------------------------------------- |
pascal void TimerAction(EventLoopTimerRef theTimer, void *userData); |
UInt32 MyNumToHexString(UInt32 num, char *str); |
OSStatus MyHexStringToNum(char *str, UInt32 *num); |
OSStatus MyStringToNum(char *str, SInt32 *num); |
UInt32 MyNumToString(UInt32 num, char *str, Boolean negative); |
OSStatus GetSAPFieldValue(UInt16 *sap); |
OSStatus SetSAPFieldValue(UInt16 sap); |
OSStatus GetSNAPFieldValue(UInt8 *snap); |
OSStatus SetSNAPFieldValue(UInt8 *sap); |
OSStatus GetNumPacketsField(UInt32 *numPackets); |
OSStatus SetSendStatistics(UInt32 numPackets, UInt32 sendTime); |
OSStatus SetReceiveStatistics(UInt32 packetsReceived, UInt32 PacketsInOrder, |
UInt32 PacketsOutOfOrder, UInt32 lastPacketReceived); |
OSStatus LoadMainWindowFromNibFile(IBNibRef gNibRef); |
OSStatus LoadAboutWindowFromNibFile(IBNibRef gNibRef); |
OSStatus EnetStrToAddr(char *str, MACAddress *eaddr); |
int EnetAddrToString(MACAddress *eaddr, char *str); |
OSStatus SetEthernetAddressField(SInt32 id, MACAddress *eaddr); |
OSStatus SetResults(EnetTestData *enetTestData); |
OSStatus MyDoCancelTestButtonInterceptor(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData); |
OSStatus MyDestAddrIsMCastInterceptor(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData); |
OSStatus MyDoTestButtonInterceptor(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData); |
void AddEnetServicesToPopupMenu(EnetData *enetdata); |
void SetActiveEnetPopupMenu(UInt16 menuItem); |
OSStatus MyEnetPopupButtonInterceptor(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData); |
OSStatus MySendRcvButtonInterceptor(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData); |
OSStatus MyAppCommandInterceptor(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData); |
void Initialize(void); /* function prototypes */ |
void DisposeUPPs(); |
/******************************************************************************* |
** Initialize |
** Do stuff like InitCursor |
********************************************************************************/ |
void Initialize() /* Initialize some managers */ |
{ |
OSErr err; |
InitCursor(); |
err = Gestalt(gestaltSystemVersion, &gVerMacOS); |
if (err != noErr) |
ExitToShell(); |
else |
{ |
fprintf(stderr, "Version of Mac OS is %X\n", (int)gVerMacOS); |
if (gVerMacOS <= 0x1015) |
{ |
fprintf(stderr, "The MultiCast option for a receive socket is not supported in this release\n"); |
fprintf(stderr, "This release of the OS support a max packet size of 1499 bytes only\n"); |
} |
} |
// init the gedata array |
memset(gedata, 0, sizeof(gedata)); |
// SIGPIPE bad. |
// refer to the MoreAuthSample code for the use of MoreUNIXIgnoreSIGPIPE |
err = EXXXToOSStatus( MoreUNIXIgnoreSIGPIPE() ); |
} |
pascal void TimerAction(EventLoopTimerRef theTimer, void *userData) |
{ |
if (gSendRcvState == kCancelTest) |
{ |
SetResults(gEnetTestData); |
} |
} |
/* |
MyNumToHexString takes a UInt32 value and creates a hex string with the |
"0x" prefix |
*/ |
UInt32 MyNumToHexString(UInt32 num, char *str) |
{ |
UInt32 n, i, j, digit; |
char tmp[16]; |
n = num; |
i = j = 0; |
while (n) |
{ |
// create an inverted string |
digit = n % 0x10; |
if (digit < 10) |
tmp[j++] = '0' + digit; |
else |
tmp[j++] = 'A' + digit - 10; |
n /= 0x10; |
} |
// insert the string prefix |
str[i++] = '0'; |
str[i++] = 'x'; |
// inssert the string |
while (j != 0) |
{ |
str[i++] = tmp[--j]; |
} |
// set null termination of the string |
str[i] = 0; |
return i; |
} |
/* |
MyHexStringToNum converts a str - a "C" style string which can be prefixed with "0x" |
or 'x' and returns the value in num |
*/ |
OSStatus MyHexStringToNum(char *str, UInt32 *num) |
{ |
UInt32 i, len; |
UInt32 digit; |
// intialize the *num to 0 |
*num = 0; |
len = strlen(str); |
if (str[0] == 'x' || str[0] == 'X') |
{ |
if (len > 9) |
return -1; // string to long to fit into a UInt32 result |
else |
i = 1; |
} |
else if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) |
{ |
if (len > 10) |
return -1; // string to long to fit into a UInt32 result |
else |
i = 2; |
} |
else |
{ |
if (len > 8) |
return -1; // string to long to fit into a UInt32 result |
else |
i = 0; |
} |
while (i < len) |
{ |
digit = str[i++]; |
if (digit >= '0' && digit <= '9') |
digit -= '0'; |
else if (digit >= 'A' && digit <= 'F') |
{ |
digit += 10; |
digit -= 'A'; |
} |
else if (digit >= 'a' && digit <= 'f') |
{ |
digit += 10; |
digit -= 'a'; |
} |
else // an illegal character is in the string |
return -1; |
*num = *num * 0x10 + digit; |
} |
return noErr; |
} |
OSStatus MyStringToNum(char *str, SInt32 *num) |
{ |
UInt32 i, len; |
UInt32 digit; |
Boolean isNegative = false; |
i = 0; |
*num = 0; |
len = strlen(str); |
if (str[i] == '-') |
{ |
isNegative = true; |
i++; |
} |
while (i < len) |
{ |
if (str[i] >= '0' && str[i] <= '9') |
digit = str[i] - '0'; |
else |
return -1; |
*num = *num * 10 + digit; |
i++; |
} |
if (isNegative) |
*num *= -1; |
return noErr; |
} |
UInt32 MyNumToString(UInt32 num, char *str, Boolean negative) |
{ |
UInt32 n, i, j; |
char tmp[16]; |
n = num; |
i = j = 0; |
if (negative) |
str[i] = '-'; |
if (n != 0) |
{ |
while (n) |
{ |
// create an inverted string |
tmp[j++] = '0' + (n % 10); |
n /= 10; |
} |
} |
else |
tmp[j++] = '0'; |
// now move the inverted string into the str |
while (j != 0) |
{ |
str[i++] = tmp[--j]; |
} |
// set null termination of the string |
str[i] = 0; |
return i; |
} |
OSStatus GetSAPFieldValue(UInt16 *sap) |
{ |
ControlID controlID = { kTestSignature, kDSAPField }; |
ControlRef control; |
UInt32 len; |
OSStatus err = noErr; |
UInt32 value; |
char str[16]; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
err = GetControlData(control, kControlNoPart, kControlEditTextTextTag, |
sizeof(str), str, &len); |
require_noerr(err, CantGetControlData); |
str[len] = 0; |
err = MyHexStringToNum(str, &value); |
require_noerr(err, InvalidData); |
*sap = value; |
return noErr; |
InvalidData: |
fprintf(stderr, "Invalid hx data in control %ld\n", controlID.id); |
return err; |
CantGetControlData: |
fprintf(stderr, "Unable to find control data - control %ld, error was %d\n", controlID.id, (int)err); |
return err; |
CantGetControlByID: |
fprintf(stderr, "Unable to find control ID %ld, error was %d\n", controlID.id, (int)err); |
return err; |
} |
OSStatus SetSAPFieldValue(UInt16 sap) |
{ |
ControlID controlID = { kTestSignature, kDSAPField }; |
ControlRef control; |
OSStatus err = noErr; |
UInt32 len; |
char str[16]; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
len = MyNumToHexString(gSAPAddr, str); |
if (len > 0) |
{ |
err = SetControlData(control, kControlNoPart, kControlStaticTextTextTag, len, &str); |
require_noerr(err, CantSetControlData); |
} |
return noErr; |
CantSetControlData: |
fprintf(stderr, "Unable to set control data %ld, error was %d\n", controlID.id, (int)err); |
return err; |
CantGetControlByID: |
fprintf(stderr, "Unable to find control ID %ld, error was %d\n", controlID.id, (int)err); |
return err; |
} |
OSStatus GetSNAPFieldValue(UInt8 *snap) |
{ |
ControlID controlID = { kTestSignature, kSNAPField }; |
ControlRef control; |
UInt32 len; |
OSStatus err = noErr; |
UInt32 value; |
UInt32 offset; |
UInt32 i; |
char str[16]; |
char temp1[2], temp2[2]; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
err = GetControlData(control, kControlNoPart, kControlEditTextTextTag, sizeof(str), str, &len); |
require_noerr(err, CantGetControlData); |
str[len] = 0; |
offset = 0; |
if((str[0] == 'x') || (str[0] == 'X')) |
offset = 1; |
else if((str[1] == 'x') || (str[1] == 'X')) |
offset = 2; |
// create a 1 char string to pass to the MyHexStringToNum function |
temp1[1] = temp2[1] = 0; |
for (i = 0; i < 5; i++) |
{ |
// get the upper byte character |
temp1[0] = str[offset + 2 * i]; |
// get the lower byte character |
temp2[0] = str[offset + 2 * i + 1]; |
// convert the upper byte |
err = MyHexStringToNum(temp1, &value); |
if (err) |
break; |
// set the upper byte of the snapAddr |
snap[i] = value << 4; |
// convert the lower byte character |
err = MyHexStringToNum(temp2, &value); |
if (err) |
break; |
// set the lower byte of the snapAddr |
snap[i] += value; |
} |
require_noerr(err, InvalidData); |
return noErr; |
InvalidData: |
fprintf(stderr, "Invalid hx data in control %ld\n", controlID.id); |
memset(snap, 0, 5); // zero out the snap address |
return err; |
CantGetControlData: |
fprintf(stderr, "Unable to find control data - control %ld, error was %d\n", controlID.id, (int)err); |
return err; |
CantGetControlByID: |
fprintf(stderr, "Unable to find control ID %ld, error was %d\n", controlID.id, (int)err); |
return err; |
} |
OSStatus SetSNAPFieldValue(UInt8 *snap) |
{ |
ControlID controlID = { kTestSignature, kSNAPField }; |
ControlRef control; |
OSStatus err = noErr; |
UInt32 len; |
UInt32 i, val; |
char str[16]; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
// the snap address is a 5 byte value, which we will prefix with "0x" |
str[0] = '0'; |
str[1] = 'x'; |
for (i = 0; i < 5; i++) |
{ |
// set the higher digit |
val = snap[i] / 16; |
if ((val >= 0) && (val <= 9)) |
str[2 * i + 2] = '0' + val; |
else if ((val >= 10) && (val <= 15)) |
str[2 * i + 2] = 'A' + val - 10; |
else |
return -1; |
// set the lower digit |
val = snap[i] % 16; |
if ((val >= 0) && (val <= 9)) |
str[2 * i + 3] = '0' + val; |
else if ((val >= 10) && (val <= 15)) |
str[2 * i + 3] = 'A' + val - 10; |
else |
return -1; |
} |
str[12] = 0; |
len = 12; |
err = SetControlData(control, kControlNoPart, kControlStaticTextTextTag, len, &str); |
require_noerr(err, CantSetControlData); |
return noErr; |
CantGetControlByID: |
fprintf(stderr, "Unable to find control ID %ld, error was %d\n", controlID.id, (int)err); |
return err; |
CantSetControlData: |
fprintf(stderr, "Unable to set control ID %ld, error was %d\n", controlID.id, (int)err); |
return err; |
} |
OSStatus SetControlState(WindowRef window, OSType type, SInt32 id, Boolean enable) |
{ |
OSStatus err; |
ControlID controlID; |
ControlRef control; |
controlID.signature = type; |
controlID.id = id; |
err = GetControlByID(window, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
if (enable) |
{ |
err = ActivateControl(control); |
require_noerr(err, CantEnableControl); |
} |
else |
{ |
err = DeactivateControl(control); |
require_noerr(err, CantDisableControl); |
} |
return noErr; |
CantGetControlByID: |
fprintf(stderr, "Unable to find control ID %ld, error was %d\n", id, (int)err); |
return err; |
CantEnableControl: |
fprintf(stderr, "Unable to enable control %ld, error was %d\n", id, (int)err); |
return err; |
CantDisableControl: |
fprintf(stderr, "Unable to disable control %ld, error was %d\n", id, (int)err); |
return err; |
} |
OSStatus SetStateOfSendReceiveFields(void) |
{ |
ControlID controlID = { kTestSignature, kSendReceiveButton }; |
ControlRef control; |
OSStatus err = noErr; |
Boolean sendState, recvState; |
if (gSendRcvState != kCancelTest) |
{ |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
// get the state of the Send Receive buttons |
gSendRcvState = GetControlValue(control); |
if (gSendRcvState == kSendTest) |
{ |
SetEthernetAddressField(kSourceAddressField, &gedata[gCurrPopupEntry-1].macAddress); |
SetEthernetAddressField(kDestAddressField, &gDestAddr); |
// enable the send fields |
// disable the receive fields |
sendState = kEnable; |
recvState = kDisable; |
} |
else |
{ |
// set the source address as a generic broadcast address and |
// the destination address as the |
SetEthernetAddressField(kSourceAddressField, &gBroadcastAddr); |
SetEthernetAddressField(kDestAddressField, &gedata[gCurrPopupEntry-1].macAddress); |
// enable the receive fields |
// disable the send fields |
sendState = kDisable; |
recvState = kEnable; |
} |
// these fields are always enabled for send and received |
SetControlState(gMainWindow, kTestSignature, kSendReceiveButton, kEnable); |
SetControlState(gMainWindow, kTestSignature, kDSAPField, kEnable); |
SetControlState(gMainWindow, kTestSignature, kSNAPField, kEnable); |
SetControlState(gMainWindow, kTestSignature, kSourceAddressField, kEnable); |
SetControlState(gMainWindow, kTestSignature, kDestAddressField, kEnable); |
SetControlState(gMainWindow, kTestSignature, kDoTestButton, kEnable); |
// the test button is always disabled when not running a test |
SetControlState(gMainWindow, kTestSignature, kCancelTestButton, kDisable); |
} |
else |
{ |
// in the CancelTest state, all fields and buttons are disabled except the |
// CancelTest button and the quit button |
SetControlState(gMainWindow, kTestSignature, kDoTestButton, kDisable); |
SetControlState(gMainWindow, kTestSignature, kSendReceiveButton, kDisable); |
// the test button is always disabled when not running a test |
SetControlState(gMainWindow, kTestSignature, kCancelTestButton, kEnable); |
sendState = kDisable; |
recvState = kDisable; |
SetControlState(gMainWindow, kTestSignature, kDSAPField, kDisable); |
SetControlState(gMainWindow, kTestSignature, kSNAPField, kDisable); |
SetControlState(gMainWindow, kTestSignature, kSourceAddressField, kEnable); |
} |
// set the stat of the send fields |
SetControlState(gMainWindow, kTestSignature, kNumPacketsField, sendState); |
// set the state of the receive fields |
SetControlState(gMainWindow, kTestSignature, kDestAddressIsMCast, recvState); |
SetControlState(gMainWindow, kTestSignature, kNumPacketsReceivedField, kDisable); |
SetControlState(gMainWindow, kTestSignature, kNumPacketsInOrderField, kDisable); |
SetControlState(gMainWindow, kTestSignature, kNumPacketsOutOfOrderField, kDisable); |
SetControlState(gMainWindow, kTestSignature, kLastPacketReceivedField, kDisable); |
// leave the kDestAddressIsMCast radio button disabled if the current MacOS is 10.1.5 or |
// earlier since the SetMulticast feature does not work |
if (gVerMacOS <= 0x1015) |
SetControlState(gMainWindow, kTestSignature, kDestAddressIsMCast, kDisable); |
else |
SetControlState(gMainWindow, kTestSignature, kDestAddressIsMCast, recvState); |
return noErr; |
CantGetControlByID: |
fprintf(stderr, "Error in setting data for Send Statistics - %ld\n", err); |
return err; |
} |
OSStatus GetNumPacketsField(UInt32 *numPackets) |
{ |
ControlID controlID = { kTestSignature, kNumPacketsField }; |
ControlRef control; |
UInt32 len; |
char str[16]; |
OSStatus err; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
// get the control text |
err = GetControlData(control, kControlNoPart, kControlEditTextTextTag, |
sizeof(str), str, &len); |
require_noerr(err, CantGetControlData); |
// force string to be a "C" style string |
str[len] = 0; |
// convert the string |
err = MyStringToNum(str, numPackets); |
require_noerr(err, InvalidStringData); |
return noErr; |
InvalidStringData: |
CantGetControlByID: |
CantGetControlData: |
return err; |
} |
OSStatus SetSendStatistics(UInt32 numPackets, UInt32 sendTime) |
{ |
ControlID controlID = { kTestSignature, kNumPacketsField }; |
ControlRef control; |
UInt32 len, rate; |
char str[16]; |
OSStatus err; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
len = MyNumToString(numPackets, str, kPositive); |
// set the control text |
err = SetControlData(control, kControlNoPart, kControlStaticTextTextTag, len, str); |
require_noerr(err, CantSetControlData); |
// fprintf(stderr, "set num packets sent field to %s\n", str); |
controlID.id = kSendTimeField; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
len = MyNumToString(sendTime, str, kPositive); |
err = SetControlData(control, kControlNoPart, kControlStaticTextTextTag, len, &str); |
require_noerr(err, CantSetControlData); |
// fprintf(stderr, "set time field to %s\n", str); |
if (sendTime > 0) |
rate = numPackets / sendTime; |
else |
rate = 0; |
controlID.id = kTransferRateField; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
len = MyNumToString(rate, str, kPositive); |
// set the control data |
err = SetControlData(control, kControlNoPart, kControlStaticTextTextTag, len, str); |
require_noerr(err, CantSetControlData); |
// fprintf(stderr, "set rate field to %s\n", str); |
SetControlState(gMainWindow, kTestSignature, kSendTimeField, FALSE); |
SetControlState(gMainWindow, kTestSignature, kTransferRateField, FALSE); |
return noErr; |
CantGetControlByID: |
CantSetControlData: |
fprintf(stderr, "Error in setting data for Send Statistics - %d\n", (int)err); |
return err; |
} |
OSStatus SetReceiveStatistics(UInt32 packetsReceived, UInt32 PacketsInOrder, |
UInt32 PacketsOutOfOrder, UInt32 lastPacketReceived) |
{ |
ControlID controlID = { kTestSignature, kNumPacketsReceivedField }; |
ControlRef control; |
UInt32 len; |
char str[16]; |
OSStatus err; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
len = MyNumToString(packetsReceived, str, kPositive); |
// set the control data |
err = SetControlData(control, kControlNoPart, kControlStaticTextTextTag, len, str); |
require_noerr(err, CantSetControlData); |
// fprintf(stderr, "Num Packets received - %d\n", (int)packetsReceived); |
controlID.id = kNumPacketsInOrderField; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
len = MyNumToString(PacketsInOrder, str, kPositive); |
// set the control data |
err = SetControlData(control, kControlNoPart, kControlStaticTextTextTag, len, str); |
require_noerr(err, CantSetControlData); |
// fprintf(stderr, "Packets in order - %d\n", (int)PacketsInOrder); |
controlID.id = kNumPacketsOutOfOrderField; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
len = MyNumToString(PacketsOutOfOrder, str, kPositive); |
// set the control data |
err = SetControlData(control, kControlNoPart, kControlStaticTextTextTag, len, str); |
require_noerr(err, CantSetControlData); |
// fprintf(stderr, "Packets out of order - %d\n", (int)PacketsOutOfOrder); |
controlID.id = kLastPacketReceivedField; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
len = MyNumToString(lastPacketReceived, str, kPositive); |
// set the control data |
err = SetControlData(control, kControlNoPart, kControlStaticTextTextTag, len, str); |
require_noerr(err, CantSetControlData); |
// fprintf(stderr, "Last packet received - %d\n", (int)lastPacketReceived); |
SetControlState(gMainWindow, kTestSignature, kNumPacketsReceivedField, FALSE); |
SetControlState(gMainWindow, kTestSignature, kNumPacketsInOrderField, FALSE); |
SetControlState(gMainWindow, kTestSignature, kNumPacketsOutOfOrderField, FALSE); |
SetControlState(gMainWindow, kTestSignature, kLastPacketReceivedField, FALSE); |
return noErr; |
CantGetControlByID: |
CantSetControlData: |
fprintf(stderr, "Error in setting data for Receive Statistics - %d\n", (int)err); |
return err; |
} |
OSStatus SetEnetPopupButton(EnetData *enet, UInt32 itemno) |
{ |
OSStatus err; |
ControlID controlID = { kTestSignature, kEnetPopupButton }; |
ControlRef control; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
CantGetControlByID: |
fprintf(stderr, "SetEnetPopupButton: Unable to get a control for the main window - control number %ld.\n", controlID.id); |
return err; |
} |
OSStatus LoadMainWindowFromNibFile(IBNibRef gNibRef) |
{ |
ControlID controlID = { kTestSignature, kDoTestButton }; |
EventTypeSpec connectEvents = { kEventClassControl, kEventControlHit }; |
EventTypeSpec popConnectEvents[] = { { kEventClassMenu, kEventMenuTargetItem }, { kEventClassMenu, kEventMenuEndTracking } }; |
OSStatus err; |
ControlRef control; |
MenuRef menuRef; |
// Create a window. "MainWindow" is the name of the window object. This name is set in |
// InterfaceBuilder when the nib is created. |
err = CreateWindowFromNib(gNibRef, CFSTR("MainWindow"), &gMainWindow); |
require_noerr(err, CantCreateWindow); |
// set up the UPP's for "Do Test" button proc handler |
if (gMyDoTestButtonInterceptorUPP == NULL) |
{ |
gMyDoTestButtonInterceptorUPP = NewEventHandlerUPP(MyDoTestButtonInterceptor); |
} |
// set the "Do Test" button as the default button |
controlID.id = kDoTestButton; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
SetWindowDefaultButton(gMainWindow, control); |
if (gMyDoTestButtonInterceptorUPP != NULL) |
{ |
InstallControlEventHandler(control, gMyDoTestButtonInterceptorUPP, 1, &connectEvents, NULL, NULL); |
} |
// set up the UPP's for "Cancel Test" button proc handler |
if (gMyDoCancelTestButtonInterceptorUPP == NULL) |
{ |
gMyDoCancelTestButtonInterceptorUPP = NewEventHandlerUPP(MyDoCancelTestButtonInterceptor); |
} |
// set the "Do Test" button as the default button |
controlID.id = kCancelTestButton; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
if (gMyDoCancelTestButtonInterceptorUPP != NULL) |
{ |
InstallControlEventHandler(control, gMyDoCancelTestButtonInterceptorUPP, 1, &connectEvents, NULL, NULL); |
} |
// set up the UPP's for "Send/Receive" button proc handler |
if (gMySendRcvButtonInterceptorUPP == NULL) |
{ |
gMySendRcvButtonInterceptorUPP = NewEventHandlerUPP(MySendRcvButtonInterceptor); |
} |
// set the interceptor for the Send/Receive radio button |
controlID.id = kSendReceiveButton; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
if (gMySendRcvButtonInterceptorUPP != NULL) |
{ |
InstallControlEventHandler(control, gMySendRcvButtonInterceptorUPP, 1, &connectEvents, NULL, NULL); |
} |
// set up the UPP's for "Dest Addr is Multicast" radio button |
if (gMyDestAddrIsMCastInterceptorUPP == NULL) |
{ |
gMyDestAddrIsMCastInterceptorUPP = NewEventHandlerUPP(MyDestAddrIsMCastInterceptor); |
} |
// set the interceptor for the "Dest Addr is Multicast" radio button |
controlID.id = kDestAddressIsMCast; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
if (gMyDestAddrIsMCastInterceptorUPP != NULL) |
{ |
InstallControlEventHandler(control, gMyDestAddrIsMCastInterceptorUPP, 1, &connectEvents, NULL, NULL); |
} |
// set up the UPP's for "enet popup" button |
if (gMyEnetPopupCommandInterceptorUPP == NULL) |
{ |
gMyEnetPopupCommandInterceptorUPP = NewEventHandlerUPP(MyEnetPopupButtonInterceptor); |
} |
// set the "enet popup" button control handler function |
controlID.id = kEnetPopupButton; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
if (gMyEnetPopupCommandInterceptorUPP != NULL) |
{ |
menuRef = GetControlPopupMenuHandle(control); |
InstallMenuEventHandler(menuRef, gMyEnetPopupCommandInterceptorUPP, 2, (EventTypeSpec*) &popConnectEvents, NULL, NULL); |
} |
// get the ethernet address data, as well as the bsd name, and an indication whether the item is |
// built in. On return gNumEnetEntries is the number of ethernet entries which were found. |
err = GetEthernetAddressInfo((EnetData*)&gedata, &gNumEnetEntries); |
if (err != noErr) |
{ |
fprintf(stderr, "an error occured in trying to find ethernet interfaces %ld\n", err); |
} |
else if (gNumEnetEntries == 0) |
{ |
fprintf(stderr, "no ethernet interfaces were found.\n"); |
err = -1; |
} |
else |
{ |
AddEnetServicesToPopupMenu((EnetData*) &gedata); |
} |
SetSAPFieldValue(gSAPAddr); |
SetSNAPFieldValue((UInt8*)&gSNAPAddr); |
SetStateOfSendReceiveFields(); |
SetSendStatistics(gNumPacketsToHandle, 0); |
// set up the timer proc |
gMainLoop = GetMainEventLoop(); |
gTimerUPP = NewEventLoopTimerUPP(TimerAction); |
err = InstallEventLoopTimer(gMainLoop, 1, 1, gTimerUPP, NULL, &gTimerRef); |
require_noerr(err, CantInstallTimer); |
return err; |
CantCreateWindow: |
fprintf(stderr, "Unable to create the main.\n"); |
return err; |
CantGetControlByID: |
fprintf(stderr, "Unable to get a control for the main window - control number %ld.\n", controlID.id); |
return err; |
CantInstallTimer: |
fprintf(stderr, "Unable to install timer %ld.\n", err); |
return err; |
} |
OSStatus |
LoadAboutWindowFromNibFile(IBNibRef gNibRef) |
{ |
OSStatus err; |
ControlID controlID = { kTestSignature, kAboutAppNameText }; |
ControlRef control; |
ControlFontStyleRec fontRec; |
CFBundleRef myBundle; |
CFDictionaryRef myDictionary; |
CFStringRef appNameCFString; |
CFStringRef versionCFString; |
char appName[kMaxInputSize]; |
char version[kMaxInputSize]; |
// Then create a window. "gAboutWindow" is the name of the window object. This name is set in |
// InterfaceBuilder when the nib is created. |
err = CreateWindowFromNib(gNibRef, CFSTR("AboutWindow"), &gAboutWindow); |
require_noerr(err, CantCreateWindow); |
myBundle = CFBundleGetMainBundle(); |
myDictionary = CFBundleGetInfoDictionary(myBundle); |
appNameCFString = CFDictionaryGetValue(myDictionary, CFSTR("CFBundleExecutable")); |
versionCFString = CFDictionaryGetValue(myDictionary, CFSTR("CFBundleVersion")); |
CFStringGetCString(appNameCFString, appName, kMaxInputSize, CFStringGetSystemEncoding()); |
CFStringGetCString(versionCFString, version, kMaxInputSize, CFStringGetSystemEncoding()); |
GetControlByID(gAboutWindow, &controlID, &control); |
fontRec.flags = kControlUseFontMask | kControlUseFaceMask | kControlAddToMetaFontMask | kControlUseJustMask; |
fontRec.style = bold; |
fontRec.just = teCenter; |
fontRec.font = kControlFontBigSystemFont; |
SetControlFontStyle(control, &fontRec); |
SetControlData(control, kControlNoPart, kControlEditTextTextTag, strlen(appName), appName); |
controlID.id = kAboutVersionText; |
GetControlByID(gAboutWindow, &controlID, &control); |
fontRec.flags = kControlUseFontMask | kControlAddToMetaFontMask | kControlUseJustMask; |
fontRec.just = teCenter; |
fontRec.font = kControlFontSmallSystemFont; |
SetControlFontStyle(control, &fontRec); |
SetControlData(control, kControlNoPart, kControlEditTextTextTag, strlen(version), version); |
CantCreateWindow: |
return err; |
} |
int EnetAddrToString(MACAddress *eaddr, char *str) |
{ |
UInt32 i; |
UInt32 digit1, digit2, len; |
UInt8 *addr = (UInt8*)eaddr; |
len = 0; |
for (i = 0; i < kIOEthernetAddressSize; i++) |
{ |
digit1 = addr[i]; |
digit1 = addr[i] / 0x10; |
digit2 = addr[i] % 0x10; |
if (digit1 < 10) |
str[len++] = '0' + digit1; |
else |
str[len++] = 'A' + (digit1 - 10); |
if (digit2 < 10) |
str[len++] = '0' + digit2; |
else |
str[len++] = 'A' + (digit2 - 10); |
if (i + 1 < kIOEthernetAddressSize) |
str[len++] = ':'; |
} |
str[len] = 0; |
return len; |
} |
OSStatus EnetStrToAddr(char *str, MACAddress *eaddr) |
{ |
UInt32 i; |
UInt32 digit1, j; |
UInt8 *addr = (UInt8*)eaddr; |
i = 0; |
memset(eaddr, 0, sizeof(MACAddress)); |
for (j = 0; j < (3 * kIOEthernetAddressSize - 1); j++) |
{ |
if (((j + 1) % 3) != 0) // do not look at the separator character |
{ |
if (str[j] >= '0' && str[j] <= '9') |
digit1 = str[j] - '0'; |
else if (str[j] >= 'A' && str[j] <= 'F') |
digit1 = 10 + str[j] - 'A'; |
else if (str[j] >= 'a' && str[j] <= 'f') |
digit1 = 10 + str[j] - 'a'; |
else |
{ |
return -1; // invalid character detected |
} |
addr[i] = addr[i] * 0x10 + digit1; |
} |
else // increment the eaddr field assignment character when j equates to the field position |
// for the separator character. |
i++; |
} |
return noErr; |
} |
OSStatus SetEthernetAddressField(SInt32 id, MACAddress *eaddr) |
{ |
OSStatus err; |
ControlID controlID; |
ControlRef control; |
char enetstr[32]; |
UInt32 len; |
controlID.signature = kTestSignature; |
controlID.id = id; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
len = EnetAddrToString(eaddr, enetstr); |
// set the control data |
err = SetControlData(control, kControlNoPart, kControlStaticTextTextTag, len, enetstr); |
require_noerr(err, CantSetControlData); |
return noErr; |
CantSetControlData: |
CantGetControlByID: |
fprintf(stderr, "SetEthernetAddressField: error occured in get/set control data\n"); |
return err; |
} |
OSStatus GetEthernetAddressField(SInt32 id, MACAddress *eaddr) |
{ |
OSStatus err; |
ControlID controlID; |
ControlRef control; |
char enetstr[32]; |
UInt32 len; |
controlID.signature = kTestSignature; |
controlID.id = id; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
err = GetControlData(control, kControlNoPart, kControlEditTextTextTag, |
sizeof(enetstr), enetstr, &len); |
require_noerr(err, CantGetControlData); |
// force the string to be a "C" style string |
enetstr[len] = 0; |
err = EnetStrToAddr(enetstr, eaddr); |
require_noerr(err, CantConvertData); |
return noErr; |
CantConvertData: |
CantGetControlData: |
CantGetControlByID: |
fprintf(stderr, "GetEthernetAddressField: error occured in get/set control data\n"); |
return err; |
} |
void AddEnetServicesToPopupMenu(EnetData *enetdata) |
{ |
ControlID controlID = { kTestSignature, kEnetPopupButton }; |
ControlRef control; |
CFStringRef tempEnet = NULL; |
char tempEnetString[256]; |
MenuRef menu; |
OSStatus err = noErr; |
UInt16 i, enetItem, enetStrLen; |
err = GetControlByID(gMainWindow, &controlID, &control); |
if (err == noErr) |
{ |
for (enetItem = 0; enetItem < gNumEnetEntries; enetItem++) |
{ |
strcpy(tempEnetString, enetdata[enetItem].bsdName); |
enetStrLen = strlen(tempEnetString); |
for (i = 0; i < enetStrLen; i++) tempEnetString[i] = toupper(tempEnetString[i]); |
if (enetdata[enetItem].isBuiltIn) |
strcat(tempEnetString, " Built-in\0"); |
tempEnet = CFStringCreateWithCString(NULL, tempEnetString, CFStringGetSystemEncoding()); |
if (tempEnet) |
{ |
menu = GetControlPopupMenuHandle(control); |
if (enetItem == 0) |
{ |
// replace the first item |
err = SetMenuItemTextWithCFString(menu, 1, tempEnet); |
if (err != noErr) |
{ |
fprintf(stderr, "Failed to set menu item %d\n", enetItem); |
} |
} |
else |
{ |
// append the menu item |
err = AppendMenuItemTextWithCFString(menu, tempEnet, 0, 0, NULL); |
if (err != noErr) |
{ |
fprintf(stderr, "Failed to append menu item %d\n", enetItem); |
} |
} |
CFRelease(tempEnet); |
} |
} |
SetControlMaximum(control, gNumEnetEntries); |
} |
else |
fprintf(stderr, "Enable to get main window control\n"); |
} |
void SetActiveEnetPopupMenu(UInt16 menuItem) |
{ |
ControlID controlID = { kTestSignature, kEnetPopupButton }; |
ControlRef control; |
OSStatus err; |
err = GetControlByID(gMainWindow, &controlID, &control); |
if (err == noErr) |
{ |
SetControlValue(control, menuItem); |
} |
} |
OSStatus MyEnetPopupButtonInterceptor(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData) |
{ |
OSStatus err = noErr; |
static SInt16 menuItem = 0; // static item to keep track of recently selected item |
// across calls to this interceptor |
switch ( GetEventKind(inEvent) ) |
{ |
case kEventMenuTargetItem: |
GetEventParameter(inEvent, kEventParamMenuItemIndex, typeMenuItemIndex, NULL, sizeof(typeMenuItemIndex), NULL, &menuItem); |
break; |
case kEventMenuEndTracking: |
if ((menuItem != gCurrPopupEntry) && (menuItem != 0)) |
{ |
if (menuItem <= gNumEnetEntries) |
{ |
gCurrPopupEntry = menuItem; |
SetActiveEnetPopupMenu(menuItem); |
err = SetStateOfSendReceiveFields(); |
} |
} |
break; |
} |
return err; |
} |
/* |
SetResults is called after a successful test to put the results into the dialog. |
The results are stored in the EnetTestData structure. |
*/ |
OSStatus SetResults(EnetTestData *testData) |
{ |
OSStatus status = noErr; |
if (testData->sendRcvState == kSendTest) |
{ |
// enter send test fields |
status = SetSendStatistics(testData->numPacketsSent, testData->tdiff); |
} |
else |
{ |
// enter receive test fields |
status = SetReceiveStatistics(testData->packetsRead, testData->packetsInOrder, |
testData->packetsOutOfOrder, testData->lastPacketNum); |
} |
return status; |
} |
OSStatus MyDoCancelTestButtonInterceptor(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData) |
{ |
OSStatus err = noErr; |
fprintf(stderr, "entered MyDoCancelTestButtonInterceptor\n"); |
gEnetTestData->sendRcvState = kCancelTest; |
err = DoEnetTest(gEnetTestData); |
// test was for receive test, so set the fields back to the receive state |
SetResults(gEnetTestData); |
gSendRcvState = kReceiveTest; |
SetStateOfSendReceiveFields(); |
return err; |
} |
OSStatus MyDestAddrIsMCastInterceptor(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData) |
{ |
OSStatus err = noErr; |
ControlID controlID = { kTestSignature, kDestAddressIsMCast }; |
ControlRef control; |
err = GetControlByID(gMainWindow, &controlID, &control); |
require_noerr(err, CantGetControlByID); |
// get the state of the Send Receive buttons |
gDestAddrIsMCast = GetControlValue(control); |
return noErr; |
CantGetControlByID: |
return err; |
} |
OSStatus MyDoTestButtonInterceptor(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData) |
{ |
OSStatus err = noErr; |
// zero out the test memory structure |
memset(gEnetTestData, 0, sizeof(*gEnetTestData)); |
// get the current SAP value setting |
err = GetSAPFieldValue(&(gEnetTestData->sap)); |
require_noerr(err, CantGetSAPData); |
fprintf(stderr, "DSAP value is 0x%X\n", gEnetTestData->sap); |
// save the current version of the OS |
gEnetTestData->verMacOS = gVerMacOS; |
gEnetTestData->destAddrIsMCast = gDestAddrIsMCast; |
// read the current SNAP value if the SAP is 0xAA |
if (gEnetTestData->sap == 0xAA) |
{ |
err = GetSNAPFieldValue((UInt8*)&(gEnetTestData->snap)); |
require_noerr(err, CantGetSNAPData); |
} |
// get the source address to be used |
err = GetEthernetAddressField(kSourceAddressField, &(gEnetTestData->srcaddr)); |
require_noerr(err, CantGetSourceEthernetAddress); |
// get the destination address to be used |
err = GetEthernetAddressField(kDestAddressField, &(gEnetTestData->destaddr)); |
require_noerr(err, CantGetDestEthernetAddress); |
err = GetNumPacketsField(&(gEnetTestData->numPacketsToSend)); |
require_noerr(err, CantGetNumPackets); |
gEnetTestData->sendRcvState = gSendRcvState; |
// copy the name of the selected enet hw based on the selected popup item |
// so that we can do a bind |
strcpy(gEnetTestData->saddr.sa_data, gedata[gCurrPopupEntry-1].bsdName); |
fprintf(stderr, "Processing packets on ethernet port %s\n", gEnetTestData->saddr.sa_data); |
// determine if this is the first time we are using this ethernet device. |
// if the device is inactive and is not the built in device, then the first time |
// the socket is used, the driver will outbound packets until the link has |
// been established. |
gEnetTestData->isFirstTime = FALSE; |
if ((gedata[gCurrPopupEntry-1].isBuiltIn == FALSE) && (gedata[gCurrPopupEntry-1].usedPreviously == FALSE)) |
{ |
gedata[gCurrPopupEntry-1].usedPreviously = TRUE; |
gEnetTestData->isFirstTime = TRUE; |
} |
err = DoEnetTest(gEnetTestData); |
if (err) |
fprintf (stderr, "error occurred on processing DoEnetTest %ld\n", err); |
else |
{ |
switch (gSendRcvState) |
{ |
case kReceiveTest: |
gSendRcvState = kCancelTest; |
// by setting the SendRcvState to kCancelTest, the DoTest button is inactivated |
// and the Cancel Test button is activated. |
SetStateOfSendReceiveFields(); |
break; |
case kSendTest: |
gEnetTestData->tdiff = gEnetTestData->tend - gEnetTestData->tbegin; |
fprintf(stderr, "sent %ld packets in %ld seconds\n", gEnetTestData->numPacketsSent, gEnetTestData->tdiff); |
SetResults(gEnetTestData); |
break; |
} |
} |
return noErr; |
CantGetNumPackets: |
CantGetDestEthernetAddress: |
CantGetSourceEthernetAddress: |
CantGetSAPData: |
CantGetSNAPData: |
return noErr; |
} |
OSStatus MySendRcvButtonInterceptor(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData) |
{ |
OSStatus err = noErr; |
err = SetStateOfSendReceiveFields(); |
return err; |
} |
OSStatus MyAppCommandInterceptor(EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData) |
{ |
HICommand theCommand; |
OSStatus status = noErr; |
status = GetEventParameter(inEvent, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &theCommand); |
if (status) |
return status; |
switch (theCommand.commandID) |
{ |
case kHICommandAbout: |
if ( MacIsWindowVisible(gAboutWindow) == false ) |
{ |
if ( LoadAboutWindowFromNibFile(gNibRef) == noErr) |
{ |
RepositionWindow(gAboutWindow, NULL, kWindowCenterOnMainScreen); |
BringToFront(gAboutWindow); |
ShowWindow(gAboutWindow); |
} |
} |
else |
{ |
ActivateWindow(gAboutWindow, true); |
BringToFront(gAboutWindow); |
} |
break; |
default: |
status = CallNextEventHandler(inCallRef, inEvent); |
break; |
} |
return status; |
} |
void DisposeUPPs() |
{ |
if (gMyDestAddrIsMCastInterceptorUPP) |
{ |
DisposeEventHandlerUPP(gMyDestAddrIsMCastInterceptorUPP); |
gMyDestAddrIsMCastInterceptorUPP = NULL; |
} |
if (gMyDoTestButtonInterceptorUPP) |
{ |
DisposeEventHandlerUPP(gMyDoTestButtonInterceptorUPP); |
gMyDoTestButtonInterceptorUPP = NULL; |
} |
if (gMyEnetPopupCommandInterceptorUPP) |
{ |
DisposeEventHandlerUPP(gMyEnetPopupCommandInterceptorUPP); |
gMyEnetPopupCommandInterceptorUPP = NULL; |
} |
if (gMyDoCancelTestButtonInterceptorUPP) |
{ |
DisposeEventHandlerUPP(gMyDoCancelTestButtonInterceptorUPP); |
gMyDoCancelTestButtonInterceptorUPP = NULL; |
} |
if (gMySendRcvButtonInterceptorUPP) |
{ |
DisposeEventHandlerUPP(gMySendRcvButtonInterceptorUPP); |
gMySendRcvButtonInterceptorUPP = NULL; |
} |
if (gMyAppCommandInterceptorUPP) |
{ |
DisposeEventHandlerUPP(gMyAppCommandInterceptorUPP); |
gMyAppCommandInterceptorUPP = NULL; |
} |
} |
int main (void) |
{ |
OSStatus err; |
EventTypeSpec commandEvents = { kEventClassCommand, kEventProcessCommand }; |
// This simply launches the 'Console.app' to show the output from this program. |
LSOpenCFURLRef(CFURLCreateWithString(NULL, CFSTR("/var/tmp/console.log"), NULL), NULL); |
Initialize(); |
// Create a Nib reference passing the name of the nib file (without the .nib extension) |
// CreateNibReference only searches into the application bundle. |
err = CreateNibReference(CFSTR("BSDLLCTest"), &gNibRef); |
require_noerr(err, CantGetNibRef); |
// Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar |
// object. This name is set in InterfaceBuilder when the nib is created. |
err = SetMenuBarFromNib(gNibRef, CFSTR("MainMenu")); |
require_noerr(err, CantSetMenuBar); |
if (gMyAppCommandInterceptorUPP == NULL) |
{ |
gMyAppCommandInterceptorUPP = NewEventHandlerUPP(MyAppCommandInterceptor); |
} |
if (gMyAppCommandInterceptorUPP != NULL) |
{ |
// I'm only using this for the About Box. |
InstallApplicationEventHandler(gMyAppCommandInterceptorUPP, 1, &commandEvents, NULL, NULL); |
} |
err = LoadMainWindowFromNibFile(gNibRef); |
require_noerr(err, CantCreateWindow); |
InitCursor(); |
// The window was created hidden so show it. |
RepositionWindow(gMainWindow, NULL, kWindowCenterOnMainScreen); |
ShowWindow(gMainWindow); |
// Call the event loop |
RunApplicationEventLoop(); |
// stop the event timer |
RemoveEventLoopTimer(gTimerRef); |
// We don't need the nib reference anymore. |
DisposeNibReference(gNibRef); |
DisposeUPPs(); |
fprintf(stderr, "\nProgram ended\n"); |
return 0; |
CantCreateWindow: |
CantSetMenuBar: |
CantGetNibRef: |
fprintf(stderr, "\nProgram ended\n"); |
return err; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-06-12