Retro68 icon indicating copy to clipboard operation
Retro68 copied to clipboard

Are there known problems compiling with MacTCP referencing code?

Open JesseCake opened this issue 5 years ago • 3 comments

I've been working away trying to learn the basics of accessing the MacTCP library and how to send a simple packet, to then build on to make OSC aware apps for the classic 68k mac.

I've been trying for days to figure out if it's me or something more, and I'm starting to wonder if it's something to do with the build chain?

The code compiles, and runs on the mac, but I don't seem to be passing any traffic at all, I even watched carefully in wireshark on another machine and don't seem to see anything happening. Are there known issues?

I've attached my test code that attempts to send a single byte via UDP here in case I've missed something (below - let me know if there's a better way to present this code)

Many thanks in advance, Jesse

#include <stdio.h>
#include <Sound.h>

//MacTCP Library built into retro68:
#include <MacTCP.h>
#include <Devices.h>
#include <string.h>
#include <Aliases.h>
#include <Errors.h>
//memory allocation library
#include <stdlib.h>

//The preferred buffer size for Macintosh channels.

#define CHANNEL_BUF_SIZE	8192

//UDP Receive buffer
char * receiveBuffer;

//place to store the stream ID
StreamPtr connectionID;

///////////////////////////////////////////
// GLobals
///////////////////////////////////////////

//driver reference number:
static short driverRefNum;
//related to opening connections:
unsigned long _stream = 0;
//Socket buffer size
//static int socketBufferSize = CHANNEL_BUF_SIZE;

/*
 * Hack fix for MacTCP 1.0.X bug
 *
 * This hack doesn't work on the PPC. But then, people with new machines
 * shouldn't run ancient buggy software. -- Jack.
 */
 
pascal char *ReturnA5(void) = {0x2E8D};


////////////////////////////////////////////////
// Functions to call for setting up the network
////////////////////////////////////////////////


////////////////////////////////////////////////
//Starts the driver
////////////////////////////////////////////////

OSErr DriverInit(){
	OSErr err;

	/*if (driverRefNum == 0){
		ParamBlockRec pb; 
		OSErr io; 
		
		pb.ioParam.ioCompletion = 0L; 
		pb.ioParam.ioNamePtr = "\p.IPP"; 
		pb.ioParam.ioPermssn = fsCurPerm; 
		io = PBOpen(&pb,false); 
		if (io != noErr) 
			SysBeep(30);
			SysBeep(30);
			SysBeep(30);
			return(io); 
		driverRefNum = pb.ioParam.ioRefNum; 
		printf("driver number ", driverRefNum);
	}
	*/
	err = OpenDriver("\p.IPP",&driverRefNum);
	if (err != noErr){
		SysBeep(30);
		printf("Error Opening Stream");
		return err;
	}
		
	return err;
		
	

}


////////////////////////////////////////////////
//Starts the stream
////////////////////////////////////////////////

OSErr StreamInit(){
	OSErr err;
	
	//set up the parameter block		
	UDPiopb upb;

	//allocate memory for the buffer correctly (no random access):
	receiveBuffer = malloc(CHANNEL_BUF_SIZE);

	//now the stream
	upb.ioCRefNum = driverRefNum;
	upb.ioCompletion = NULL;
	upb.csCode = UDPCreate;
	//upb.udpStream = 1;
	upb.csParam.create.rcvBuff = receiveBuffer;	
	upb.csParam.create.rcvBuffLen = 8192;
	upb.csParam.create.notifyProc = NULL;
	//upb.csParam.create.localPort = 1100;
	err = PBControlSync((ParmBlkPtr)&upb);
	

	//check this worked and beep 4 times if not:
	if (err != noErr){
		SysBeep(30);
		printf("Error Opening Stream");
		return err;
	}

	else {
	//harvest the stream ID we've just created for sending the packet
	connectionID = upb.udpStream;
	return upb.udpStream;	
	}

}

////////////////////////////////////////////////
//Sends a packet
////////////////////////////////////////////////

OSErr SendPacket(){
	OSErr err;
	
	//set up the parameter block		
	UDPiopb upb;

	udp_port outport = 5000;
	ip_addr outhost = (192,168,8,6);

	char data = 'b';
	wdsEntry wds[2];

	wds[0].length = 1;
	wds[0].ptr = &data;
	wds[1].length = 0;

	upb.ioCRefNum = driverRefNum;
	upb.csCode = UDPWrite;
	upb.udpStream = connectionID; // is this right?
	//upb.udpStream = 1;	
	upb.csParam.send.remoteHost = outhost;
	upb.csParam.send.remotePort = outport;
	upb.csParam.send.wdsPtr = (Ptr)wds;
	upb.csParam.send.sendLength = 0;
	upb.csParam.send.checkSum = 1;
		
	err = PBControlSync((ParmBlkPtr)&upb);
		
	//check this worked and beep 4 times if not:
	if (err != noErr){
		SysBeep(30);
		printf("Error Sending Packet");
		return err;
	}

}

//////////////////////////////////////////////////////
// Close the stream
//////////////////////////////////////////////////////
OSErr CloseStream(){
	OSErr err;

	//set up the parameter block		
	UDPiopb upb;

	upb.ioCRefNum = driverRefNum;
	upb.csCode = UDPRelease;
	upb.udpStream = connectionID;
	//upb.udpStream = 1;	
	upb.ioCompletion = NULL; 
	
	err = PBControlSync((ParmBlkPtr) &upb);
	if (err != noErr){
		SysBeep(30);
		printf("Error Closing Stream");
		return err;
	}
}


////////////////////////////////////////////////////////////////////////////////////////
//MAIN loop
///////////////////////////////////////////////////////////////////////////////////////

int main(int argc, char** argv){

	OSErr feedback;

	/////////////////////////////////////
	// Then shows us the hello world:
	/////////////////////////////////////
	

    	printf("Hello, world.\n");

	////////////////////////////////////////////////////////////////////////////////
	//Runs our network routine to test:
	////////////////////////////////////////////////////////////////////////////////
	printf("Driver Init: ");	
	DriverInit();
	printf("done\n");
	//SysBeep(30);

	printf("Stream Init: \n");
	feedback = StreamInit(); //passing name of receive buffer for the stream into argument
	printf("Stream ID: ", feedback);	
	printf("done\n");
	//connectionID = feedback;
	//SysBeep(30);

	//printf("Stream ID: ");
	//printf(&connectionID);
	//printf("\n");

	for (int i = 0; i <= 5; i++){
		//char inputdata = 'b';
		printf("Send Packet: ");
		SendPacket();
		printf("done\n");
	}


	printf("Close Stream: ");
	CloseStream(); //close it down before we exit
	printf("done\n");

	SysBeep(30);

    	printf("\n(Press Return)\n");
    	getchar();
    	return 0;
}

JesseCake avatar Apr 28 '20 08:04 JesseCake

No, I'm not aware of any toolchain-related problems, except that you need Apple's original Universal Interfaces and not the open source replacements to even compile any networking stuff.

I have never tried to use UDP with either MacTCP or OpenTrasport, but the LaunchAPPLServer app (source code in the Retro68 repository) uses both for TCP connections.

autc04 avatar May 03 '20 10:05 autc04

here's a MacTCP UDP demo, it sets up and then sends one packet

not tested on m68k hardware, but runs correctly in an emulator

cy384 avatar May 16 '20 05:05 cy384

Thanks so much - unfortunately as I was working on this my physical mac I was using died a sudden death (as 30 year old macs tend to) so I'll test it when I can find time to troubleshoot it. Thanks

JesseCake avatar May 25 '20 08:05 JesseCake