home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sys.mac.programmer
- Path: sparky!uunet!stanford.edu!leland.Stanford.EDU!bolo.stanford.edu!cheshire
- From: Stuart Cheshire <cheshire@cs.stanford.edu>
- Subject: Re: Looking for some sample appletalk ATP code...
- Message-ID: <1992Sep2.175833.1365@leland.Stanford.EDU>
- X-Xxmessage-Id: <A6CA4EBFCC020010@bolo.stanford.edu>
- X-Xxdate: Wed, 2 Sep 92 18:58:07 GMT
- Sender: news@leland.Stanford.EDU (Mr News)
- Organization: Stanford University
- X-Useragent: Nuntius v1.1.1d7
- References: <1992Sep1.033635.28604@sunb10.cs.uiuc.edu>
- Date: Wed, 2 Sep 92 17:58:33 GMT
- Lines: 263
-
- In article <1992Sep1.033635.28604@sunb10.cs.uiuc.edu> Alex Bratton,
- bratton@sparc3.cs.uiuc.edu writes:
- >If you have some sample code (ATP) that opens, registers, and dumps some
- >data, I'd really appreciate seeing it. This has been bugging me for a
- while
- >and I think I need to look at some working code to see what I'm missing.
-
- Here is some sample code which includes ATP calls. It is the code I use
- to obtain the list of AppleTalk zones to display in my game Bolo, and
- judging by the time it took to get all the wrinkles worked out, and make
- it run with both Phase 1 and Phase 2, it probably should be in some
- sample code library somewhere for other people's use.
-
- The ATP calls are in the Phase 1 part, which has to communicate directly
- with the bridge via ATP.
-
- The code gets the list of zones, sorts them into alphabetical order using
- heap sort, and then appends them in order to the list identified by the
- parameter "zonelist", which should be initialized before calling
- getzonelist.
-
- The code is written for Think C 5.
-
- #include <AppleTalk.h>
-
- #define local static
- #define export
- #define import extern
-
- typedef struct
- {
- BYTE sysLAPAddr;
- BYTE destnode;
- BYTE srcnode;
- BYTE ALAPproto;
- WORD length;
- union
- {
- struct
- {
- BYTE destsocket;
- BYTE srcsocket;
- BYTE DPPproto;
- BYTE userdata[15];
- } shortheader;
- struct
- {
- WORD checksum;
- WORD destnet;
- WORD srcnet;
- BYTE destnode;
- BYTE srcnode;
- BYTE destsocket;
- BYTE srcsocket;
- BYTE DPPproto;
- BYTE userdata[7];
- } longheader;
- } u;
- BYTE unused;
- BYTE sysABridge;
- WORD sysNetNum;
- WORD vSCCEnable;
- } MPPglobals;
-
- extern MPPglobals *ABusVars : 0x2D8;
-
- #define atpMaxData 578 // size of buffer for zone names
- #define kZIPSocket 6 // the Zone Information Protocol socket
- #define kATPTimeOutVal 3 // re-try ATP SendRequest every 3 seconds
- #define kATPRetryCount 5 // for five times
- #define kGZLCall 0x08000000 // GetZoneList indicator
- #define kGMZCall 0x07000000 // GetMyZone indicator
- #define kZoneCount 0x0000FFFF // mask to count zones in buffer
- #define kNoMoreZones 0xFF000000 // mask to see if more zones to come
-
- #define xCall 246
- #define zipGetLocalZones 5
- #define zipGetZoneList 6
- #define zipGetMyZone 7
-
- typedef struct
- {
- QElemPtr qLink;
- short qType;
- short ioTrap;
- Ptr ioCmdAddr;
- ProcPtr ioCompletion;
- OSErr ioResult;
- StringPtr ioNamePtr;
- short ioVRefNum;
- short ioRefNum;
- short csCode;
- short xppSubCode;
- unsigned char xppTimeOut;
- unsigned char xppRetry;
- short filler;
- Ptr zipBuffPtr;
- short zipNumZones;
- short zipLastFlag;
- short zipInfoField[35];
- } xCallParam;
-
- #define MAX_ZONES 1000
- typedef struct { unsigned char c[34]; } ZONE_NAME;
- ZONE_NAME *zone_array, **zone_heap;
- local int num_zones;
-
- local void addtoheap(int place, ZONE_NAME *new)
- {
- int parent = (place-1)>>1;
- zone_heap[place]=new;
- while (place>0 && IUCompString(zone_heap[parent]->c,
- zone_heap[place]->c)>0)
- {
- ZONE_NAME *temp = zone_heap[place ];
- zone_heap[place ] = zone_heap[parent];
- zone_heap[parent] = temp;
- place=parent;
- parent=(place-1)>>1;
- }
- }
-
- local ZONE_NAME *removefromheap(int last) // last is index of last item
- on heap
- {
- ZONE_NAME *top = zone_heap[0]; // extract top element
- int gap = 0; // top is now empty
- int left = 1;
- int right = 2;
- while(left<=last) // move gap to bottom
- {
- if(right>last || IUCompString(zone_heap[right]->c,
- zone_heap[left]->c)>0)
- { zone_heap[gap]=zone_heap[left ]; gap=left; }
- else{ zone_heap[gap]=zone_heap[right]; gap=right; }
- left = (gap<<1)+1;
- right = left + 1;
- }
- if(last != gap) addtoheap(gap, zone_heap[last]); // fill gap
- return(top); // and heap is now one element smaller
- }
-
- local void BuildZoneListPhase1(unsigned char *myzone)
- {
- ATPParamBlock pb;
- BDSElement dBDS;
- unsigned char datapacket[atpMaxData];
- short zIndex=1, zCount=0, i;
-
- dBDS.buffSize = atpMaxData;
- dBDS.buffPtr = (Ptr)datapacket;
-
- pb.ATPatpFlags = 0;
- pb.ATPreqLength = 0;
- pb.ATPreqPointer = NULL;
- pb.ATPbdsPointer = (Ptr) &dBDS;
- pb.ATPnumOfBuffs = 1;
- pb.ATPtimeOutVal = kATPTimeOutVal;
- pb.ATPretryCount = kATPRetryCount;
-
- pb.ATPaddrBlock.aNet = ABusVars->sysNetNum;
- pb.ATPaddrBlock.aNode = GetBridgeAddress();
- pb.ATPaddrBlock.aSocket = kZIPSocket;
-
- if (!pb.ATPaddrBlock.aNode) return; // no bridge -- no zones
-
- do {
- unsigned char *ptr = datapacket;
- pb.ATPuserData = kGZLCall + zIndex;
- PSendRequest(&pb, false);
- zCount += dBDS.userBytes & kZoneCount;
- while(zIndex++ <= zCount)
- {
- int count = 1 + *ptr;
- unsigned char *dest = zone_array[num_zones].c;
- while (count-- > 0) *dest++ = *ptr++;
- addtoheap(num_zones, &zone_array[num_zones]);
- num_zones++;
- }
- } until(dBDS.userBytes & kNoMoreZones);
-
- pb.ATPuserData = kGMZCall;
- datapacket[0] = 0;
- if (PSendRequest(&pb, false) == noErr && datapacket[0] &&
- datapacket[0]<32)
- for (i=0; i<=datapacket[0]; i++) myzone[i] = datapacket[i];
- }
-
- local void BuildZoneListPhase2(unsigned char *myzone)
- {
- short XPPRefNum;
- xCallParam xpb;
- unsigned char datapacket[atpMaxData];
- short zIndex=1, zCount=0;
-
- if (OpenDriver("\p.XPP", &XPPRefNum)) return;
-
- xpb.zipInfoField[0] = 0;
- xpb.zipLastFlag = FALSE;
- xpb.ioRefNum = XPPRefNum;
- xpb.csCode = xCall;
- xpb.xppSubCode = zipGetZoneList;
- xpb.xppTimeOut = kATPTimeOutVal;
- xpb.xppRetry = kATPRetryCount;
- xpb.zipBuffPtr = (Ptr)datapacket;
-
- while (!xpb.zipLastFlag && !PBControl((ParmBlkPtr)&xpb, FALSE))
- {
- unsigned char *ptr = datapacket;
- zCount += xpb.zipNumZones;
- while(zIndex++ <= zCount)
- {
- int count = 1 + *ptr;
- unsigned char *dest = zone_array[num_zones].c;
- while (count-- > 0) *dest++ = *ptr++;
- addtoheap(num_zones, &zone_array[num_zones]);
- num_zones++;
- }
- }
-
- xpb.zipInfoField[0] = 0;
- xpb.xppSubCode = zipGetMyZone;
- xpb.zipBuffPtr = (Ptr)myzone;
- PBControl((ParmBlkPtr)&xpb, FALSE);
- // Mustn't close XPP driver (see IM V 532)
- }
-
- local short addrow(ListHandle list, unsigned char *newdata)
- {
- Point pt = { 0, 0 };
- pt.v = (*list)->dataBounds.bottom;
- LAddRow(1, pt.v, list);
- LSetCell(newdata+1, newdata[0], pt, list);
- return(pt.v);
- }
-
- export int getzonelist(ListHandle zonelist)
- {
- unsigned char myzone[33];
- Point pt = { 0, 0 };
- SysEnvRec sysenvirons;
- SysEnvirons(1, &sysenvirons);
- zone_array = (ZONE_NAME *) NewPtr(MAX_ZONES * sizeof(ZONE_NAME ));
- zone_heap = (ZONE_NAME **) NewPtr(MAX_ZONES * sizeof(ZONE_NAME *));
- myzone[0] = num_zones = 0;
- if (sysenvirons.atDrvrVersNum < 53) BuildZoneListPhase1(myzone);
- else BuildZoneListPhase2(myzone);
-
- while (num_zones-->0) addrow(zonelist, removefromheap(num_zones)->c);
- DisposPtr((Ptr)zone_array);
- DisposPtr((Ptr)zone_heap);
-
- LSearch(myzone+1, *myzone, NULL, &pt, zonelist);
- LSetSelect(TRUE, pt, zonelist);
- LAutoScroll(zonelist);
- return(pt.v);
- }
-
-
- Stuart Cheshire <cheshire@cs.stanford.edu>
- * Liliore Green Rains Houses Resident Computer Coordinator
- * Stanford Distributed Systems Group Research Assistant
- * Macintosh Programmer
-