Topic : TOS - das Betriebssystem Author : Version : tos.hyp (5. März 2013) Subject : Programmieren/Atari Nodes : 3001 Index Size : 93602 HCP-Version : 5 Compiled on : Atari @charset : atarist @lang : @default : Titel @help : @options : +g -i -s +x +zz -t4 @width : 70 View Ref-File15.10.11 How to implement an SPA TOS Here's a step-by-step instruction on how to implement SSP as a Service providing application. All code provided here is also available as sample code in the archive in the file SPAtools.c (SPAtools.gfa for GFABasic, SPAtools.s for assembler). Use and modify as necessary :) Communication Session Make sure you understand the concept of SSP SPA-sessions. A session between an SPA and the Server is started with the SSP_SSIR message, and ended when the SPA sends SSP_SPASA. For every SPA there will only be one session at a time. Multiple service requests by SRAs will be queued, and sent one after another. This might be changed in future implementations because of not being able to perform another service while a session is active, which is a drawback in case of Delayed Response services. 1. Receiving Service Initialization Request and determining the information type The SPA (your application) will receive the SSP_SSIR message to indicate use of a service your application provides. The Server knows the services provided by your application from the Server registration, so you will only receive requests for services you actually provide. The message-buffer with SSP_SSIR: [0] = SSP_SSIR [1] = serviceID [1] = requestID [2] = sessionID serviceID (messagebuf[1]) is the requested service. This in conjunction with requestID will give your application an idea as of which information to provide. requestID (messagebuf[2]) is an identification that tells you which information to provide to the Server. For example, if Send File Service has been requested by the user, you will receive SSP_RECIPIENTS as requestID. Build a list of possible recipients (depending on the type of your application) separated by CRLF, terminated by NULL. If your application is an IRC Client for example, provide a list of online users that can currently be seen in open channels. For an email Client, provide a list of email addresses from your favorites. Provide only users that can be actually reached at the time; in IRC or ICQ, for example, provide only online users. For a SSP_DISPLAYMESSAGE service as serviceID, if your application is an IRC Client, say, provide a list of open channels and open chats. sessionID is used to distinguish between multiple sessions. For now, this will always be 0. 2. Initializing the service and providing information 2.1 Creating a shared memory file The information the Server has requested is sent by your application in a shared memory file. Whether one has to be created or not depends on the serviceID. There is a unique name for every shm-file used for each service request, the name of the file is built by the following conventions: u:/shm/[applID]_init[sessionID].ssp For example, if your application has appl_id 25 and sessionID is 0: u:/shm/25_init0.ssp After you have built the name for the shared memory file, use @{"Fcreate" ignore} to create the file. Read/Write access rights have to be set correctly, depending on the request type! Then, bind the memory block that contains the requested information (list of recipients, etc., depending on requestID and serviceID) to the file using Fcntl. The following code will build the filename and open an initialization data shared memory file when calling createShmFile: int createShmFile(int access, void *memPtr, int sessionID){ int fHandle; char *filename = buildInitFilename(sessionID); fHandle = Fcreate(filename, access); Fcntl(fHandle, memPtr, SHMSETBLK); return(fHandle); } char *buildInitFilename(int sessionID){ static char filename[256] = "u:/shm/"; char tmpstring[4]; strcat(&filename, itoa(appl_id, tmpstring, 10)); strcat(&filename, "_init"); strcat(&filename, itoa(sessionID, tmpstring, 10)); strcat(&filename, ".ssp"); return(&filename); } 2.2.2 Sending Service Initialization Send an SSP_SPASI message to the Server, filling the AES message- buffer with the following values: [0] = SSP_SPASI [1] = sessionID sessionID(messagebuf[1]) The session ID sent to you with SSP_SSIR. 3. Receiving Service Use Request When your application receives SSP_SSUR, this means that a service should be performed now. messagebuf[1] will contain the serviceID also received in SSP_SSIR. This makes it possible for you to keep initializing and performing services separate from one another. The serviceID will be the same throughout one session. messagebuf[2] will contain the same sessionID as in SSP_SSIR. messagebuf[3]/[4] will build a LONG that is the number of the information part of all the parts you provided in SSP_SPASI. For example, if you have sent 10 recipients for a Send File Service request, and this LONG is 0, the first recipient in the list is to receive the file. messagebuf[5] and messagebuf[6] contain 2 different ID numbers for a shared memory file, shmID1 and shmID2. Build a filename like this: u:/shm/[shmID1]_data[shmID2].ssp For example, if shmID1 is 25 and shmID2 is 0: u:/shm/25_data0.ssp(!nl) This is the file that contains the data necessary to perform the service. The contents of the shared memory block depend on serviceID: SSP_SENDFILE, SSP_UPLOADFILE, SSP_COMPRESSFILE: the shm-block will contain a NULL-terminated file path and name. SSP_SENDMSG, SSP_DISPLAYMSG: the shm-block will contain a NULL- terminated string to display or send. SSP_DISPLAYINFO: the shm-block will be an empty buffer with space for information about your current status with read/write access rights. Copy NULL-terminated text information into the shm-block. The maximum length will be in shmPar1 (messagebuf[7])! SSP_CONTEXT: no shared memory file will exist. Don't try to open it ;) SSP_STATUSDISPLAY: the shm-block will contain icon data. The following code will build the filename, open the data shared memory file and return a pointer to the shm-block when calling openDataShm. The parameter access should be either FO_READ or FO_WRITE, depending on what the serviceID is: void *openDataShm(int shmId1, int shmId2, int access){ int fHandle; char *filename = buildDataFilename(shmId1, shmId2); fHandle = Fopen(filename, access); Fcntl(fHandle, memPtr, SHMGETBLK); return(fHandle); } char *buildDataFilename(int shmId1, int shmId2){ static char filename[256] = "u:/shm/"; char tmpstring[4]; strcat(&filename, itoa(shmId1, tmpstring, 10)); strcat(&filename, "_init"); strcat(&filename, itoa(shmId2, tmpstring, 10)); strcat(&filename, ".ssp"); return(&filename); } Remember to close the shared memory file as soon as you don't need to read from or write to it any more (before acknowledging the Server) with Fclose! Delete the initialization shm-file when receiving SSP_SSUR and free temporary memory, if any! 4. Performing the Service and acknowledging 4.1 Performing the Service Depending on the parameters sent in SSP_SSUR you can determine what to do. Ultimately the way your application performs certain services is up to you, and also depends on the type of your application. See 'Guidelines for performing services' for a general direction to go to. 4.2 Acknowledging Acknowledging a service is done by sending SSP_SPASA to the Server. When you do this depends on your application and on the type of service (IRS or DRS). With Immediate Response Services, you should start performing the service (e.g. open a connection to a user and start sending a file) and acknowledge before the service is actually finished. With Delayed Response Services (e.g. the Compress File Service) acknowledging should not be done before the service is completely performed (e.g. the files are compressed). 5. Guidelines for performing services 5.1 Send File Service For online Clients like IRC and ICQ: When receiving SSP_SSIR with SSP_RECIPIENTS, only provide online users that a file can actually be sent to in the recipients list. After opening a connection and starting to send the file, acknowledge immediately. For email and news Clients: In the recipient information, provide recipients from your favorites. Encode the file into an attachment, and open an email editor window for typing in text. Make sure the received attachment and the typed email go out together. 5.2 Send Message Service For online Clients like IRC and ICQ: For SSP_RECIPIENTS, provide a list only of open chats or chat channels. Receive the message and post it to the user. Acknowledge immediately. For email and news Clients: Receive the message and put it into an email as text. Configurably, post an alert box to provide the possibility to edit the message and add attachments for the user. Only open the email editor window if the user answers this question with 'Yes'. Acknowledge as soon as the user has answered the question. If this security request is turned off, send immediately. 5.2 Display Message Service For online Clients like IRC and ICQ: You will not receive SSP_RECIPIENTS. This service can be triggered with user interaction as well as automatically. Decide in which window of your application to display the message. Prefer topped, uniconified, unshaded, visible windows. Do not send the text message over network connections. For email and news Clients, text editors and similar: You will not receive SSP_RECIPIENTS. Insert the text message into the currently top open email editor window. If none is open, open one with no recipient and insert the message there. 5.3 Upload File Service For FTP Clients: Provide a list of recipients in shm as described here. Retrieve the Server and directory name from the shm-block provided with SSP_SSUR, and upload the file. Acknowledge after opening the connection and starting to upload. 5.4 Status Display Service Retrieve the icon data, copy it into your own buffers. Display new icon. Acknowledge. 5.5 Display Information Service Copy information text, NULL terminated, to the shm-block provided. Acknowledge. 5.6 Context Popup Service Retrieve coordinates for the context popup from the message-buffer. Open context popup in context to the current status icon from the Status Display Service. Make frequently used and status dependend options available in the context popup. Make all information available in the context popup also available directly by your application! The context popup is never to supersede generally available options! 5.7 Compress File Service Provide different archive types and compression levels after receiving SSP_FORMATS. Use the format number contained in sspPar1 at SSP_SSUR. If sspPar1 is -1, use default format and compression level. Retrieve file or folder names to compress. Archive files to provided archive name and -path. Acknowledge after compression and archiving is finished. 5.8 General ∙ Try to make performing services transparent to the user. When started from the Server (your commandline will be 'SSP_START'), don't open any unnecessary windows, try to restrict the screen output to what is necessary for performing the service. If you're started with 'SSP_START' in your commandline, wait 3 seconds after performing your service, and then exit. Chances are that queued requests will come through in this time, and if not, chances are the user doesn't need your application anymore for now ;) Exit without any screen output and user input, unless it's absolutely inevitable! ∙ After implementing SSP, switch the Server into debug mode and try requesting your provided services with different applications. If everything works and the Server outputs no error or warning messages, your implementation is OK. ∙ Remember, the user doesn't care much about how it works, only that it works.