home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / sys / mac / programm / 14895 < prev    next >
Encoding:
Text File  |  1992-09-02  |  7.7 KB  |  278 lines

  1. Newsgroups: comp.sys.mac.programmer
  2. Path: sparky!uunet!stanford.edu!leland.Stanford.EDU!bolo.stanford.edu!cheshire
  3. From: Stuart Cheshire <cheshire@cs.stanford.edu>
  4. Subject: Re: Looking for some sample appletalk ATP code...
  5. Message-ID: <1992Sep2.175833.1365@leland.Stanford.EDU>
  6. X-Xxmessage-Id: <A6CA4EBFCC020010@bolo.stanford.edu>
  7. X-Xxdate: Wed, 2 Sep 92 18:58:07 GMT
  8. Sender: news@leland.Stanford.EDU (Mr News)
  9. Organization: Stanford University
  10. X-Useragent: Nuntius v1.1.1d7
  11. References: <1992Sep1.033635.28604@sunb10.cs.uiuc.edu>
  12. Date: Wed, 2 Sep 92 17:58:33 GMT
  13. Lines: 263
  14.  
  15. In article <1992Sep1.033635.28604@sunb10.cs.uiuc.edu> Alex Bratton,
  16. bratton@sparc3.cs.uiuc.edu writes:
  17. >If you have some sample code (ATP) that opens, registers, and dumps some
  18. >data, I'd really appreciate seeing it.  This has been bugging me for a
  19. while
  20. >and I think I need to look at some working code to see what I'm missing.
  21.  
  22. Here is some sample code which includes ATP calls. It is the code I use
  23. to obtain the list of AppleTalk zones to display in my game Bolo, and
  24. judging by the time it took to get all the wrinkles worked out, and make
  25. it run with both Phase 1 and Phase 2, it probably should be in some
  26. sample code library somewhere for other people's use.
  27.  
  28. The ATP calls are in the Phase 1 part, which has to communicate directly
  29. with the bridge via ATP.
  30.  
  31. The code gets the list of zones, sorts them into alphabetical order using
  32. heap sort, and then appends them in order to the list identified by the
  33. parameter "zonelist", which should be initialized before calling
  34. getzonelist.
  35.  
  36. The code is written for Think C 5.
  37.  
  38. #include <AppleTalk.h>
  39.  
  40. #define local static
  41. #define export
  42. #define import extern
  43.  
  44. typedef struct
  45.     {
  46.     BYTE sysLAPAddr;
  47.     BYTE destnode;
  48.     BYTE srcnode;
  49.     BYTE ALAPproto;
  50.     WORD length;
  51.     union
  52.         {
  53.         struct
  54.             {
  55.             BYTE destsocket;
  56.             BYTE srcsocket;
  57.             BYTE DPPproto;
  58.             BYTE userdata[15];
  59.             } shortheader;
  60.         struct
  61.             {
  62.             WORD checksum;
  63.             WORD destnet;
  64.             WORD srcnet;
  65.             BYTE destnode;
  66.             BYTE srcnode;
  67.             BYTE destsocket;
  68.             BYTE srcsocket;
  69.             BYTE DPPproto;
  70.             BYTE userdata[7];
  71.             } longheader;
  72.         } u;
  73.     BYTE unused;
  74.     BYTE sysABridge;
  75.     WORD sysNetNum;
  76.     WORD vSCCEnable;
  77.     } MPPglobals;
  78.  
  79. extern MPPglobals *ABusVars : 0x2D8;
  80.  
  81. #define        atpMaxData                578            // size of buffer for zone names
  82. #define        kZIPSocket                6            // the Zone Information Protocol socket
  83. #define        kATPTimeOutVal            3            // re-try ATP SendRequest every 3 seconds
  84. #define        kATPRetryCount            5            // for five times
  85. #define        kGZLCall                0x08000000    // GetZoneList indicator
  86. #define        kGMZCall                0x07000000    // GetMyZone indicator
  87. #define        kZoneCount                0x0000FFFF     // mask to count zones in buffer
  88. #define        kNoMoreZones            0xFF000000     // mask to see if more zones to come
  89.  
  90. #define xCall               246
  91. #define zipGetLocalZones    5
  92. #define zipGetZoneList      6
  93. #define zipGetMyZone        7
  94.  
  95. typedef struct
  96.     {
  97.     QElemPtr         qLink;
  98.     short            qType;
  99.     short            ioTrap;
  100.     Ptr              ioCmdAddr;
  101.     ProcPtr          ioCompletion;
  102.     OSErr            ioResult;
  103.     StringPtr        ioNamePtr;
  104.     short            ioVRefNum;
  105.     short            ioRefNum;
  106.     short            csCode;
  107.     short            xppSubCode;
  108.     unsigned char    xppTimeOut;
  109.     unsigned char    xppRetry;
  110.     short            filler;
  111.     Ptr              zipBuffPtr;
  112.     short            zipNumZones;
  113.     short            zipLastFlag;
  114.     short            zipInfoField[35];
  115.     } xCallParam;
  116.  
  117. #define MAX_ZONES 1000
  118. typedef struct { unsigned char c[34]; } ZONE_NAME;
  119. ZONE_NAME *zone_array, **zone_heap;
  120. local int num_zones;
  121.  
  122. local void addtoheap(int place, ZONE_NAME *new)
  123.     {
  124.     int parent = (place-1)>>1;
  125.     zone_heap[place]=new;
  126.     while (place>0 && IUCompString(zone_heap[parent]->c,
  127. zone_heap[place]->c)>0)
  128.         {
  129.         ZONE_NAME *temp   = zone_heap[place ];
  130.         zone_heap[place ] = zone_heap[parent];
  131.         zone_heap[parent] = temp;
  132.         place=parent;
  133.         parent=(place-1)>>1;
  134.         }
  135.     }
  136.  
  137. local ZONE_NAME *removefromheap(int last)    // last is index of last item
  138. on heap
  139.     {
  140.     ZONE_NAME *top = zone_heap[0];            // extract top element
  141.     int gap   = 0;                            // top is now empty
  142.     int left  = 1;
  143.     int right = 2;
  144.     while(left<=last)                        // move gap to bottom
  145.         {
  146.         if(right>last || IUCompString(zone_heap[right]->c,
  147. zone_heap[left]->c)>0)
  148.             { zone_heap[gap]=zone_heap[left ]; gap=left;  }
  149.         else{ zone_heap[gap]=zone_heap[right]; gap=right; }
  150.         left  = (gap<<1)+1;
  151.         right = left + 1;
  152.         }
  153.     if(last != gap) addtoheap(gap, zone_heap[last]);    // fill gap
  154.     return(top);    // and heap is now one element smaller
  155.     }
  156.  
  157. local void BuildZoneListPhase1(unsigned char *myzone)
  158.     {
  159.     ATPParamBlock    pb;
  160.     BDSElement        dBDS;
  161.     unsigned char    datapacket[atpMaxData];
  162.     short            zIndex=1, zCount=0, i;
  163.  
  164.     dBDS.buffSize    = atpMaxData;
  165.     dBDS.buffPtr     = (Ptr)datapacket;
  166.  
  167.     pb.ATPatpFlags   = 0;
  168.     pb.ATPreqLength  = 0;
  169.     pb.ATPreqPointer = NULL;
  170.     pb.ATPbdsPointer = (Ptr) &dBDS;
  171.     pb.ATPnumOfBuffs = 1;
  172.     pb.ATPtimeOutVal = kATPTimeOutVal;
  173.     pb.ATPretryCount = kATPRetryCount;
  174.  
  175.     pb.ATPaddrBlock.aNet    = ABusVars->sysNetNum;
  176.     pb.ATPaddrBlock.aNode   = GetBridgeAddress();
  177.     pb.ATPaddrBlock.aSocket = kZIPSocket;
  178.  
  179.     if (!pb.ATPaddrBlock.aNode) return;        // no bridge -- no zones
  180.  
  181.     do    {
  182.         unsigned char *ptr = datapacket;
  183.         pb.ATPuserData = kGZLCall + zIndex;
  184.         PSendRequest(&pb, false);
  185.         zCount += dBDS.userBytes & kZoneCount;
  186.         while(zIndex++ <= zCount)
  187.             {
  188.             int count = 1 + *ptr;
  189.             unsigned char *dest = zone_array[num_zones].c;
  190.             while (count-- > 0) *dest++ = *ptr++;
  191.             addtoheap(num_zones, &zone_array[num_zones]);
  192.             num_zones++;
  193.             }
  194.         } until(dBDS.userBytes & kNoMoreZones);
  195.     
  196.     pb.ATPuserData = kGMZCall;
  197.     datapacket[0] = 0;
  198.     if (PSendRequest(&pb, false) == noErr && datapacket[0] &&
  199. datapacket[0]<32)
  200.         for (i=0; i<=datapacket[0]; i++) myzone[i] = datapacket[i];
  201.     }
  202.  
  203. local void BuildZoneListPhase2(unsigned char *myzone)
  204.     {
  205.     short XPPRefNum;
  206.     xCallParam        xpb;
  207.     unsigned char    datapacket[atpMaxData];
  208.     short            zIndex=1, zCount=0;
  209.     
  210.     if (OpenDriver("\p.XPP", &XPPRefNum)) return;
  211.  
  212.     xpb.zipInfoField[0] = 0;
  213.     xpb.zipLastFlag = FALSE;
  214.     xpb.ioRefNum    = XPPRefNum;
  215.     xpb.csCode      = xCall;
  216.     xpb.xppSubCode  = zipGetZoneList;
  217.     xpb.xppTimeOut  = kATPTimeOutVal;
  218.     xpb.xppRetry    = kATPRetryCount;
  219.     xpb.zipBuffPtr  = (Ptr)datapacket;
  220.  
  221.     while (!xpb.zipLastFlag && !PBControl((ParmBlkPtr)&xpb, FALSE))
  222.         {
  223.         unsigned char *ptr = datapacket;
  224.         zCount += xpb.zipNumZones;
  225.         while(zIndex++ <= zCount)
  226.             {
  227.             int count = 1 + *ptr;
  228.             unsigned char *dest = zone_array[num_zones].c;
  229.             while (count-- > 0) *dest++ = *ptr++;
  230.             addtoheap(num_zones, &zone_array[num_zones]);
  231.             num_zones++;
  232.             }
  233.         }
  234.  
  235.     xpb.zipInfoField[0] = 0;
  236.     xpb.xppSubCode  = zipGetMyZone;
  237.     xpb.zipBuffPtr  = (Ptr)myzone;
  238.     PBControl((ParmBlkPtr)&xpb, FALSE);
  239.     // Mustn't close XPP driver (see IM V 532)
  240.     }
  241.  
  242. local short addrow(ListHandle list, unsigned char *newdata)
  243.     {
  244.     Point pt = { 0, 0 };
  245.     pt.v = (*list)->dataBounds.bottom;
  246.     LAddRow(1, pt.v, list);
  247.     LSetCell(newdata+1, newdata[0], pt, list);
  248.     return(pt.v);
  249.     }
  250.  
  251. export int getzonelist(ListHandle zonelist)
  252.     {
  253.     unsigned char myzone[33];
  254.     Point pt = { 0, 0 };
  255.     SysEnvRec sysenvirons;
  256.     SysEnvirons(1, &sysenvirons);
  257.     zone_array = (ZONE_NAME  *) NewPtr(MAX_ZONES * sizeof(ZONE_NAME  ));
  258.     zone_heap  = (ZONE_NAME **) NewPtr(MAX_ZONES * sizeof(ZONE_NAME *));
  259.     myzone[0] = num_zones = 0;
  260.     if (sysenvirons.atDrvrVersNum < 53) BuildZoneListPhase1(myzone);
  261.     else                                BuildZoneListPhase2(myzone);
  262.     
  263.     while (num_zones-->0) addrow(zonelist, removefromheap(num_zones)->c);
  264.     DisposPtr((Ptr)zone_array);
  265.     DisposPtr((Ptr)zone_heap);
  266.  
  267.     LSearch(myzone+1, *myzone, NULL, &pt, zonelist);
  268.     LSetSelect(TRUE, pt, zonelist);
  269.     LAutoScroll(zonelist);
  270.     return(pt.v);
  271.     }
  272.  
  273.  
  274. Stuart Cheshire <cheshire@cs.stanford.edu>
  275.  * Liliore Green Rains Houses Resident Computer Coordinator
  276.  * Stanford Distributed Systems Group Research Assistant
  277.  * Macintosh Programmer
  278.