syspkt.c

Go to the documentation of this file.
00001 /*
00002  * $Id: syspkt.c,v 1.41 2006-10-12 14:21:23 desrod Exp $
00003  *
00004  * syspkt.c:  Pilot SysPkt manager
00005  *
00006  * (c) 1996, Kenneth Albanowski.
00007  * Derived from padp.c.
00008  *
00009  * This library is free software; you can redistribute it and/or modify it
00010  * under the terms of the GNU Library General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or (at
00012  * your option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful, but
00015  * WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library
00017  * General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Library General Public License
00020  * along with this library; if not, write to the Free Software Foundation,
00021  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00022  *
00023  */
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028 
00029 #include <sys/types.h>
00030 #include <sys/socket.h>
00031 #include <netinet/in.h>
00032 #include <stdlib.h>
00033 #include <stdio.h>
00034 #include <stdarg.h>
00035 #include <string.h>
00036 
00037 #include "pi-source.h"
00038 #include "pi-syspkt.h"
00039 #include "pi-slp.h"
00040 #include "pi-serial.h"
00041 #include "pi-error.h"
00042 
00043 /* Declare prototypes */
00044 static int sys_PackRegisters(void *data, struct Pilot_registers *r);
00045 
00046 
00047 /***********************************************************************
00048  *
00049  * Function:    sys_UnpackState
00050  *
00051  * Summary:     Get the state command
00052  *
00053  * Parameters:  None
00054  *
00055  * Returns:     Nothing
00056  *
00057  ***********************************************************************/
00058 int
00059 sys_UnpackState(void *buffer, struct Pilot_state *s)
00060 {
00061         int     idx;
00062         unsigned char *data = buffer;
00063 
00064         s->reset                = get_short(data);
00065         s->exception            = get_short(data + 2);
00066         memcpy(s->func_name, data + 152, 32);
00067         memcpy(s->instructions, data + 78, 30);
00068         s->func_name[32 - 1]    = 0;
00069         s->func_start           = get_long(data + 144);
00070         s->func_end             = get_long(data + 148);
00071         sys_UnpackRegisters(data + 4, &s->regs);
00072 
00073         for (idx = 0; idx < 6; idx++) {
00074                 s->breakpoint[idx].address = get_long(data + 108 + idx * 6);
00075                 s->breakpoint[idx].enabled = get_byte(data + 112 + idx * 6);
00076         }
00077 
00078         s->trap_rev = get_short(data + 184);
00079 
00080         return 0;
00081 }
00082 
00083 
00084 /***********************************************************************
00085  *
00086  * Function:    sys_UnpackRegisters
00087  *
00088  * Summary:     Read the register commands
00089  *
00090  * Parameters:  None
00091  *
00092  * Returns:     0
00093  *
00094  ***********************************************************************/
00095 int
00096 sys_UnpackRegisters(void *data, struct Pilot_registers *r)
00097 {
00098         unsigned char *buffer = data;
00099 
00100         r->D[0] = get_long(buffer + 0);
00101         r->D[1] = get_long(buffer + 4);
00102         r->D[2] = get_long(buffer + 8);
00103         r->D[3] = get_long(buffer + 12);
00104         r->D[4] = get_long(buffer + 16);
00105         r->D[5] = get_long(buffer + 20);
00106         r->D[6] = get_long(buffer + 24);
00107         r->D[7] = get_long(buffer + 28);
00108         r->A[0] = get_long(buffer + 32);
00109         r->A[1] = get_long(buffer + 36);
00110         r->A[2] = get_long(buffer + 40);
00111         r->A[3] = get_long(buffer + 44);
00112         r->A[4] = get_long(buffer + 48);
00113         r->A[5] = get_long(buffer + 52);
00114         r->A[6] = get_long(buffer + 56);
00115         r->USP  = get_long(buffer + 60);
00116         r->SSP  = get_long(buffer + 64);
00117         r->PC   = get_long(buffer + 68);
00118 
00119         r->SR   = get_short(buffer + 72);
00120 
00121         return 0;
00122 }
00123 
00124 
00125 /***********************************************************************
00126  *
00127  * Function:    sys_PackRegisters
00128  *
00129  * Summary:     Pack the register commands
00130  *
00131  * Parameters:  None
00132  *
00133  * Returns:     0
00134  *
00135  ***********************************************************************/
00136 static int
00137 sys_PackRegisters(void *data, struct Pilot_registers *r)
00138 {
00139         int     idx;
00140         unsigned char *buffer = data;
00141 
00142         for (idx = 0; idx < 8; idx++)
00143                 set_long(buffer + idx * 4, r->D[idx]);
00144         for (idx = 0; idx < 7; idx++)
00145                 set_long(buffer + 32 + idx * 4, r->A[idx]);
00146         set_long(buffer + 60, r->USP);
00147         set_long(buffer + 64, r->SSP);
00148         set_long(buffer + 68, r->PC);
00149 
00150         set_short(buffer + 72, r->SR);
00151 
00152         return 0;
00153 }
00154 
00155 /***********************************************************************
00156  *
00157  * Function:    sys_Continue
00158  *
00159  * Summary:     Define the Continue command
00160  *
00161  * Parameters:  None
00162  *
00163  * Returns:     Nothing
00164  *
00165  ***********************************************************************/
00166 int
00167 sys_Continue(int sd, struct Pilot_registers *r, struct Pilot_watch *w)
00168 {
00169         char    buf[94];
00170 
00171         buf[0]  = 0;
00172         buf[1]  = 0;
00173         buf[2]  = 0;
00174         buf[3]  = 0;
00175         buf[4]  = 0x07;
00176         buf[5]  = 0;            /* gapfill */
00177 
00178         if (!r)
00179                 return pi_write(sd, buf, 6);
00180 
00181         sys_PackRegisters(buf + 6, r);
00182         set_byte(buf + 80, (w != 0) ? 1 : 0);
00183         set_byte(buf + 81, 0);
00184         set_long(buf + 82, w ? w->address : 0);
00185         set_long(buf + 86, w ? w->length : 0);
00186         set_long(buf + 90, w ? w->checksum : 0);
00187 
00188         return pi_write(sd, buf, 94);
00189 }
00190 
00191 /***********************************************************************
00192  *
00193  * Function:    sys_Step
00194  *
00195  * Summary:     Single-step command
00196  *
00197  * Parameters:  None
00198  *
00199  * Returns:     Socket, command, 6 bytes
00200  *
00201  ***********************************************************************/
00202 int
00203 sys_Step(int sd)
00204 {
00205         char    buf[94];
00206 
00207         buf[0] = 0;
00208         buf[1] = 0;
00209         buf[2] = 0;
00210         buf[3] = 0;
00211         buf[4] = 0x03;
00212         buf[5] = 0;             /* gapfill */
00213 
00214         return pi_write(sd, buf, 6);
00215 }
00216 
00217 /***********************************************************************
00218  *
00219  * Function:    sys_SetBreakpoints
00220  *
00221  * Summary:     Set the breakpoints (0x0C, 0x8C)
00222  *
00223  * Parameters:  None
00224  *
00225  * Returns:     Nothing
00226  *
00227  ***********************************************************************/
00228 int
00229 sys_SetBreakpoints(int sd, struct Pilot_breakpoint *b)
00230 {
00231         int     idx;
00232         pi_buffer_t *buf;
00233 
00234         buf = pi_buffer_new (94);
00235         if (buf == NULL) {
00236                 errno = ENOMEM;
00237                 return pi_set_error(sd, PI_ERR_GENERIC_MEMORY);
00238         }
00239 
00240         buf->data[0] = 0;
00241         buf->data[1] = 0;
00242         buf->data[2] = 0;
00243         buf->data[3] = 0;
00244         buf->data[4] = 0x0c;
00245         buf->data[5] = 0;               /* gapfill */
00246 
00247         for (idx = 0; idx < 6; idx++) {
00248                 set_long(buf->data + 6 + idx * 6, b[idx].address);
00249                 set_byte(buf->data + 10 + idx * 6, b[idx].enabled);
00250                 set_byte(buf->data + 11 + idx * 6, 0);
00251         }
00252 
00253         pi_write(sd, buf->data, 42);
00254 
00255         idx = pi_read(sd, buf, 6);
00256 
00257         if (idx <= 0 || buf->data[4] != (unsigned char) 0x8c) {
00258                 pi_buffer_free (buf);
00259                 return 0;
00260         }
00261 
00262         pi_buffer_free (buf);
00263         return 1;
00264 }
00265 
00266 /***********************************************************************
00267  *
00268  * Function:    sys_SetTrapBreaks
00269  *
00270  * Summary:     Set the Trap Breaks (0x11, 0x91)
00271  *
00272  * Parameters:  None
00273  *
00274  * Returns:     Nothing
00275  *
00276  ***********************************************************************/
00277 int
00278 sys_SetTrapBreaks(int sd, int *traps)
00279 {
00280         int     idx;
00281         pi_buffer_t *buf;
00282 
00283         buf = pi_buffer_new (32);
00284         if (buf == NULL) {
00285                 errno = ENOMEM;
00286                 return pi_set_error(sd, PI_ERR_GENERIC_MEMORY);
00287         }
00288 
00289         buf->data[0] = 0;
00290         buf->data[1] = 0;
00291         buf->data[2] = 0;
00292         buf->data[3] = 0;
00293         buf->data[4] = 0x11;
00294         buf->data[5] = 0;               /* gapfill */
00295 
00296         for (idx = 0; idx < 5; idx++) {
00297                 set_short(buf->data + 6 + idx * 2, traps[idx]);
00298         }
00299 
00300         pi_write(sd, buf->data, 16);
00301 
00302         idx = pi_read(sd, buf, 6);
00303 
00304         if ((idx <= 0) || (buf->data[4] != (unsigned char) 0x91)) {
00305                 pi_buffer_free (buf);
00306                 return 0;
00307         }
00308 
00309         pi_buffer_free (buf);
00310         return 1;
00311 }
00312 
00313 /***********************************************************************
00314  *
00315  * Function:    sys_GetTrapBreaks
00316  *
00317  * Summary:     Get the Trap Breaks (0x10, 0x90)
00318  *
00319  * Parameters:  None
00320  *
00321  * Returns:     Nothing
00322  *
00323  ***********************************************************************/
00324 int
00325 sys_GetTrapBreaks(int sd, int *traps)
00326 {
00327         int     idx;
00328         pi_buffer_t *buf;
00329 
00330         buf = pi_buffer_new (32);
00331         if (buf == NULL) {
00332                 errno = ENOMEM;
00333                 return pi_set_error(sd, PI_ERR_GENERIC_MEMORY);
00334         }
00335 
00336         buf->data[0] = 0;
00337         buf->data[1] = 0;
00338         buf->data[2] = 0;
00339         buf->data[3] = 0;
00340         buf->data[4] = 0x10;
00341         buf->data[5] = 0;               /* gapfill */
00342 
00343         pi_write(sd, buf->data, 6);
00344 
00345         idx = pi_read(sd, buf, 16);
00346 
00347         if ((idx < 16) || (buf->data[4] != (unsigned char) 0x90)) {
00348                 pi_buffer_free (buf);
00349                 return 0;
00350         }
00351 
00352         for (idx = 0; idx < 5; idx++) {
00353                 traps[idx] = get_short(buf->data + 6 + idx * 2);
00354         }
00355 
00356         pi_buffer_free (buf);
00357         return 1;
00358 }
00359 
00360 
00361 /***********************************************************************
00362  *
00363  * Function:    sys_ToggleDbgBreaks
00364  *
00365  * Summary:     Enable the DbgBreaks command (0x0D, 0x8D)
00366  *
00367  * Parameters:  None
00368  *
00369  * Returns:     Nothing
00370  *
00371  ***********************************************************************/
00372 int
00373 sys_ToggleDbgBreaks(int sd)
00374 {
00375         int     idx;
00376         pi_buffer_t *buf;
00377         unsigned char byte;
00378 
00379         buf = pi_buffer_new (32);
00380         if (buf == NULL) {
00381                 errno = ENOMEM;
00382                 return pi_set_error(sd, PI_ERR_GENERIC_MEMORY);
00383         }
00384 
00385         buf->data[0] = 0;
00386         buf->data[1] = 0;
00387         buf->data[2] = 0;
00388         buf->data[3] = 0;
00389         buf->data[4] = 0x0d;
00390         buf->data[5] = 0;               /* gapfill */
00391 
00392         pi_write(sd, buf->data, 6);
00393 
00394         idx = pi_read(sd, buf, 7);
00395 
00396         if ((idx < 7) || (buf->data[4] != (unsigned char) 0x8d)) {
00397                 pi_buffer_free (buf);
00398                 return 0;
00399         }
00400 
00401         byte = get_byte(buf->data + 6);
00402 
00403         pi_buffer_free (buf);
00404 
00405         return byte;
00406 }
00407 
00408 
00409 /***********************************************************************
00410  *
00411  * Function:    sys_QueryState
00412  *
00413  * Summary:     Query the state (uh)
00414  *
00415  * Parameters:  None
00416  *
00417  * Returns:     Nothing
00418  *
00419  ***********************************************************************/
00420 int
00421 sys_QueryState(int sd)
00422 {
00423         char    buf[6];
00424 
00425         buf[0] = 0;
00426         buf[1] = 0;
00427         buf[2] = 0;
00428         buf[3] = 0;
00429         buf[4] = 0;
00430         buf[5] = 0;             /* gapfill */
00431 
00432         return pi_write(sd, buf, 2);
00433 }
00434 
00435 /***********************************************************************
00436  *
00437  * Function:    sys_ReadMemory
00438  *
00439  * Summary:     Read memory (0x01, 0x81)
00440  *
00441  * Parameters:  None
00442  *
00443  * Returns:     Nothing
00444  *
00445  ***********************************************************************/
00446 int
00447 sys_ReadMemory(int sd, unsigned long addr, unsigned long len, void *dest)
00448 {
00449         int     result;
00450         unsigned long todo, done;
00451         pi_buffer_t *buf;
00452 
00453         buf = pi_buffer_new (0xFFFF);
00454         if (buf == NULL) {
00455                 errno = ENOMEM;
00456                 return pi_set_error(sd, PI_ERR_GENERIC_MEMORY);
00457         }
00458 
00459         done = 0;
00460         do {
00461                 todo    = len;
00462                 if (todo > 256)
00463                         todo = 256;
00464 
00465                 buf->data[0] = 0;
00466                 buf->data[1] = 0;
00467                 buf->data[2] = 0;
00468                 buf->data[3] = 0;
00469                 buf->data[4] = 0x01;
00470                 buf->data[5] = 0;       /* gapfill */
00471 
00472                 set_long(buf->data + 6, addr + done);
00473                 set_short(buf->data + 10, todo);
00474 
00475                 pi_write(sd, buf->data, 12);
00476 
00477                 result = pi_read(sd, buf, todo + 6);
00478 
00479                 if (result < 0) {
00480                         pi_buffer_free (buf);
00481                         return done;
00482                 }
00483 
00484                 if ((buf->data[4] == 0x81)
00485                     && ((unsigned int) result == todo + 6)) {
00486                         memcpy(((char *) dest) + done, buf->data + 6, todo);
00487                         done += todo;
00488                 } else {
00489                         pi_buffer_free (buf);
00490                         return done;
00491                 }
00492         } while (done < len);
00493 
00494         pi_buffer_free (buf);
00495         return done;
00496 }
00497 
00498 
00499 /***********************************************************************
00500  *
00501  * Function:    sys_WriteMemory
00502  *
00503  * Summary:     Write memory (0x02, 0x82)
00504  *
00505  * Parameters:  None
00506  *
00507  * Returns:     Nothing
00508  *
00509  ***********************************************************************/
00510 int
00511 sys_WriteMemory(int sd, unsigned long addr, unsigned long len, void *src)
00512 {
00513         int     result;
00514         unsigned long todo, done;
00515         pi_buffer_t *buf;
00516 
00517         buf = pi_buffer_new (0xFFFF);
00518         if (buf == NULL) {
00519                 errno = ENOMEM;
00520                 return pi_set_error(sd, PI_ERR_GENERIC_MEMORY);
00521         }
00522 
00523         done = 0;
00524         do {
00525                 todo = len;
00526                 if (todo > 256)
00527                         todo = 256;
00528 
00529                 buf->data[0] = 0;
00530                 buf->data[1] = 0;
00531                 buf->data[2] = 0;
00532                 buf->data[3] = 0;
00533                 buf->data[4] = 0x02;
00534                 buf->data[5] = 0;       /* gapfill */
00535 
00536                 set_long(buf->data + 6, addr);
00537                 set_short(buf->data + 10, len);
00538                 memcpy(buf->data + 12, (char *)src + done, todo);
00539 
00540                 pi_write(sd, buf->data, len + 12);
00541 
00542                 result = pi_read(sd, buf, 6);
00543 
00544                 if (result < 0) {
00545                         pi_buffer_free (buf);
00546                         return done;
00547                 }
00548 
00549                 if ((buf->data[4] == (unsigned char)0x82)
00550                     && ((unsigned long) result == todo + 6)) {
00551                         ;
00552                 } else {
00553                         pi_buffer_free (buf);
00554                         return done;
00555                 }
00556         } while (done < len);
00557 
00558         pi_buffer_free (buf);
00559         return done;
00560 }
00561 
00562 
00563 /***********************************************************************
00564  *
00565  * Function:    sys_Find
00566  *
00567  * Summary:     Searches a range of addresses for data (0x13, 0x80)
00568  *
00569  * Parameters:  None
00570  *
00571  * Returns:     Nothing
00572  *
00573  ***********************************************************************/
00574 int
00575 sys_Find(int sd, unsigned long startaddr, unsigned long stopaddr, size_t len,
00576          int caseinsensitive, void *data, unsigned long *found)
00577 {
00578         int     result;
00579         unsigned char byte;
00580         pi_buffer_t *buf;
00581 
00582         buf = pi_buffer_new (len + 17);
00583         if (buf == NULL) {
00584                 errno = ENOMEM;
00585                 return pi_set_error(sd, PI_ERR_GENERIC_MEMORY);
00586         }
00587 
00588         buf->data[0] = 0;
00589         buf->data[1] = 0;
00590         buf->data[2] = 0;
00591         buf->data[3] = 0;
00592         buf->data[4] = 0x11;
00593         buf->data[5] = 0;               /* gapfill */
00594 
00595         set_long(buf->data + 6, startaddr);
00596         set_long(buf->data + 10, stopaddr);
00597         set_short(buf->data + 14, len);
00598         set_byte(buf->data + 16, caseinsensitive);
00599         memcpy(buf->data + 17, data, len);
00600 
00601         pi_write(sd, buf->data, len + 17);
00602 
00603         result = pi_read(sd, buf, 12);
00604 
00605         if (result < 0) {
00606                 pi_buffer_free (buf);
00607                 return result;
00608         }
00609 
00610         if (found)
00611                 *found = get_long(buf->data + 6);
00612 
00613         byte = get_byte(buf->data + 10);
00614 
00615         pi_buffer_free (buf);
00616 
00617         return byte;
00618 }
00619 
00620 
00621 /***********************************************************************
00622  *
00623  * Function:    sys_RemoteEvent
00624  *
00625  * Summary:     Parameters sent from host to target to feed pen and
00626  *              keyboard events. They do not require a response.
00627  *
00628  * Parameters:  None
00629  *
00630  * Returns:     Nothing
00631  *
00632  ***********************************************************************/
00633 int
00634 sys_RemoteEvent(int sd, int penDown, int x, int y, int keypressed,
00635                 int keymod, int keyasc, int keycode)
00636 {
00637         char    buf[16];
00638 
00639         /* Offset 1, 3 and 9 are padding */
00640         set_byte(&buf[0], 0x0D); /* RemoteEvtCommand    */
00641         set_byte(&buf[1], 0);
00642         set_byte(&buf[2], penDown);
00643         set_byte(&buf[3], 0);
00644         set_short(&buf[4], x);
00645         set_short(&buf[6], y);
00646         set_byte(&buf[8], keypressed);
00647         set_byte(&buf[9], 0);
00648         set_short(&buf[10], keymod);
00649         set_short(&buf[12], keyasc);
00650         set_short(&buf[14], keycode);
00651 
00652         return pi_write(sd, buf, 16);
00653 }
00654 
00655 
00656 /***********************************************************************
00657  *
00658  * Function:    sys_RPC
00659  *
00660  * Summary:     Remote Procedure calls (0x0A, 0x8A)
00661  *
00662  * Parameters:  None
00663  *
00664  * Returns:     Nothing
00665  *
00666  ***********************************************************************/
00667 int
00668 sys_RPC(int sd, int sockaddr, int trap, long *D0, long *A0, int params,
00669         struct RPC_param *param, int reply)
00670 {
00671         int     idx;
00672         unsigned char *c;
00673         pi_buffer_t *buf;
00674 
00675         buf = pi_buffer_new (4096);
00676         if (buf == NULL) {
00677                 errno = ENOMEM;
00678                 return pi_set_error(sd, PI_ERR_GENERIC_MEMORY);
00679         }
00680 
00681         buf->data[0] = sockaddr;        /* 0 for debug, 1 for console */
00682         buf->data[1] = sockaddr;
00683         buf->data[2] = 0;
00684         buf->data[4] = 0x0a;
00685         buf->data[5] = 0;
00686 
00687         set_short(buf->data + 6, trap);
00688         set_long(buf->data + 8, *D0);
00689         set_long(buf->data + 12, *A0);
00690         set_short(buf->data + 16, params);
00691 
00692         c = buf->data + 18;
00693         for (idx = params - 1; idx >= 0; idx--) {
00694                 set_byte(c, param[idx].byRef);
00695                 c++;
00696                 set_byte(c, param[idx].size);
00697                 c++;
00698                 if (param[idx].data)
00699                         memcpy(c, param[idx].data, param[idx].size);
00700                 c += param[idx].size;
00701                 if (param[idx].size & 1)
00702                         *c++ = 0;
00703         }
00704 
00705         if (sockaddr == 3)
00706                 set_short(buf->data + 4, c - buf->data - 6);
00707 
00708         pi_write(sd, buf->data + 4,(size_t)(c - buf->data - 4));
00709 
00710         if (reply) {
00711                 int l = pi_read(sd, buf, 4096);
00712 
00713                 if (l < 0) {
00714                         pi_buffer_free (buf);
00715                         return l;
00716                 }
00717 
00718                 if (buf->data[0] != (unsigned char)0x8a) {
00719                         pi_buffer_free (buf);
00720                         return pi_set_error(sd, -2);
00721                 }
00722 
00723                 *D0 = get_long(buf->data + 4);
00724                 *A0 = get_long(buf->data + 8);
00725                 c = buf->data + 14;
00726                 for (idx = params - 1; idx >= 0; idx--) {
00727                         if (param[idx].byRef && param[idx].data)
00728                                 memcpy(param[idx].data, c + 2,
00729                                        param[idx].size);
00730                         c += 2 + ((get_byte(c + 1) + 1) & ~1);
00731                 }
00732         }
00733 
00734         pi_buffer_free (buf);
00735         return 0;
00736 }
00737 
00738 
00739 /***********************************************************************
00740  *
00741  * Function:    RPC
00742  *
00743  * Summary:     Deprecated
00744  *
00745  * Parameters:  None
00746  *
00747  * Returns:     Nothing
00748  *
00749  ***********************************************************************/
00750 int
00751 RPC(int sd, int sockaddr, int trap, int reply, ...)
00752 {
00753         int     idx     = 0,
00754                 j,
00755                 RPC_arg[20];
00756         va_list ap;
00757         struct  RPC_param p[20];
00758         long    D0      = 0,
00759                 A0      = 0;
00760 
00761         va_start(ap, reply);
00762         for (;;) {
00763                 int type = va_arg(ap, int);
00764 
00765                 if (type == 0)
00766                         break;
00767                 if (type < 0) {
00768                         p[idx].byRef    = 0;
00769                         p[idx].size     = -type;
00770                         RPC_arg[idx]    = va_arg(ap, int);
00771 
00772                         p[idx].data     = &RPC_arg[idx];
00773                         p[idx].invert   = 0;
00774                 } else {
00775                         void *c = va_arg(ap, void *);
00776 
00777                         p[idx].byRef    = 1;
00778                         p[idx].size     = type;
00779                         p[idx].data     = c;
00780                         p[idx].invert   = va_arg(ap, int);
00781 
00782                         if (p[idx].invert) {
00783                                 if (p[idx].size == 2) {
00784                                         int *s = c;
00785 
00786                                         *s = htons(*s);
00787                                 } else {
00788                                         int *l = c;
00789 
00790                                         *l = htonl(*l);
00791                                 }
00792                         }
00793                 }
00794                 idx++;
00795         }
00796         va_end(ap);
00797 
00798         if (sys_RPC(sd, sockaddr, trap, &D0, &A0, idx, p, reply != 2) < 0)
00799             return pi_error(sd);
00800 
00801         for (j = 0; j < idx; j++) {
00802                 if (p[j].invert) {
00803                         void *c = p[j].data;
00804 
00805                         if (p[j].size == 2) {
00806                                 int *s = c;
00807 
00808                                 *s = htons(*s);
00809                         } else {
00810                                 int *l = c;
00811 
00812                                 *l = htonl(*l);
00813                         }
00814                 }
00815         }
00816 
00817         if (reply)
00818                 return A0;
00819         return D0;
00820 }
00821 
00822 
00823 /***********************************************************************
00824  *
00825  * Function:    PackRPC
00826  *
00827  * Summary:     Pack the RPC structure for transmission
00828  *
00829  * Parameters:  None
00830  *
00831  * Returns:     Nothing
00832  *
00833  ***********************************************************************/
00834 int
00835 PackRPC(struct RPC_params *p, int trap, int reply, ...)
00836 {
00837         int     idx = 0;
00838         va_list ap;
00839 
00840         p->trap = trap;
00841         p->reply = reply;
00842 
00843         va_start(ap, reply);
00844         for (;;) {
00845                 int type = (int) va_arg(ap, int);
00846 
00847                 if (type == 0)
00848                         break;
00849                 if (type < 0) {
00850                         p->param[idx].byRef     = 0;
00851                         p->param[idx].size      = -type;
00852                         p->param[idx].arg       = (int) va_arg(ap, int);
00853 
00854                         p->param[idx].data      = &p->param[idx].arg;
00855                         p->param[idx].invert    = 0;
00856                 } else {
00857                         void *c = (void *) va_arg(ap, void *);
00858 
00859                         p->param[idx].byRef     = 1;
00860                         p->param[idx].size      = type;
00861                         p->param[idx].data      = c;
00862                         p->param[idx].invert    = (int) va_arg(ap, int);
00863                 }
00864                 idx++;
00865         }
00866         p->args = idx;
00867         va_end(ap);
00868 
00869         return 0;
00870 }
00871 
00872 
00873 /***********************************************************************
00874  *
00875  * Function:    UninvertRPC
00876  *
00877  * Summary:
00878  *
00879  * Parameters:  None
00880  *
00881  * Returns:     Nothing
00882  *
00883  ***********************************************************************/
00884 void
00885 UninvertRPC(struct RPC_params *p)
00886 {
00887         int     j;
00888 
00889         for (j = 0; j < p->args; j++) {
00890                 if (p->param[j].invert) {
00891                         void *c = p->param[j].data;
00892 
00893                         if ((p->param[j].invert == 2)
00894                             && (p->param[j].size == 2)) {
00895                                 int *s = c;
00896 
00897                                 *s = htons(*s) >> 8;
00898                         } else if (p->param[j].size == 2) {
00899                                 int *s = c;
00900 
00901                                 *s = htons(*s);
00902                         } else {
00903                                 long *l = c;
00904 
00905                                 *l = htonl(*l);
00906                         }
00907                 }
00908         }
00909 }
00910 
00911 
00912 /***********************************************************************
00913  *
00914  * Function:    InvertRPC
00915  *
00916  * Summary:
00917  *
00918  * Parameters:  None
00919  *
00920  * Returns:     Nothing
00921  *
00922  ***********************************************************************/
00923 void
00924 InvertRPC(struct RPC_params *p)
00925 {
00926         int     j;
00927 
00928         for (j = 0; j < p->args; j++) {
00929                 if (p->param[j].invert) {
00930                         void *c = p->param[j].data;
00931 
00932                         if ((p->param[j].invert == 2)
00933                             && (p->param[j].size == 2)) {
00934                                 int *s = c;
00935 
00936                                 *s = ntohs(*s) >> 8;
00937                         } else if (p->param[j].size == 2) {
00938                                 int *s = c;
00939 
00940                                 *s = ntohs(*s);
00941                         } else {
00942                                 long *l = c;
00943 
00944                                 *l = ntohl((unsigned) *l);
00945                         }
00946                 }
00947         }
00948 }
00949 
00950 
00951 /***********************************************************************
00952  *
00953  * Function:    DoRPC
00954  *
00955  * Summary:     Actually execute the RPC query/response
00956  *
00957  * Parameters:  None
00958  *
00959  * Returns:     Nothing
00960  *
00961  ***********************************************************************/
00962 unsigned long
00963 DoRPC(int sd, int sockaddr, struct RPC_params *p, int *error)
00964 {
00965         int     err;
00966         long    D0 = 0,
00967                 A0 = 0;
00968 
00969         InvertRPC(p);
00970 
00971         err =
00972             sys_RPC(sd, sockaddr, p->trap, &D0, &A0, p->args, &p->param[0],
00973                     p->reply);
00974 
00975         UninvertRPC(p);
00976 
00977         if (error)
00978                 *error = err;
00979 
00980         if (p->reply == RPC_PtrReply)
00981                 return A0;
00982         else if (p->reply == RPC_IntReply)
00983                 return D0;
00984         else
00985                 return err;
00986 }
00987 
00988 
00989 /***********************************************************************
00990  *
00991  * Function:    RPC_Int_Void
00992  *
00993  * Summary:
00994  *
00995  * Parameters:  None
00996  *
00997  * Returns:     Nothing
00998  *
00999  ***********************************************************************/
01000 int
01001 RPC_Int_Void(int sd, int trap)
01002 {
01003         return RPC(sd, 1, trap, 0, RPC_End);
01004 }
01005 
01006 
01007 /***********************************************************************
01008  *
01009  * Function:    RPC_Ptr_Void
01010  *
01011  * Summary:
01012  *
01013  * Parameters:  None
01014  *
01015  * Returns:     Nothing
01016  *
01017  ***********************************************************************/
01018 int
01019 RPC_Ptr_Void(int sd, int trap)
01020 {
01021         return RPC(sd, 1, trap, 1, RPC_End);
01022 }
01023 
01024 
01025 /* vi: set ts=8 sw=4 sts=4 noexpandtab: cin */
01026 /* ex: set tabstop=4 expandtab: */
01027 /* Local Variables: */
01028 /* indent-tabs-mode: t */
01029 /* c-basic-offset: 8 */
01030 /* End: */
01031 

© 1996-2007 by pilot-link.org. All rights reserved.