Are there known problems compiling with MacTCP referencing code?
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;
}
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.
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
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