Usermode/AxWin4 - Clean up logging
[tpg/acess2.git] / Usermode / Applications / axwin3_src / libaxwin3.so_src / msg.c
1 /*
2  * AxWin3 Interface Library
3  * - By John Hodge (thePowersGang)
4  *
5  * msg.c
6  * - Message handling / IPC
7  */
8 #include <axwin3/axwin.h>
9 #include <acess/sys.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <ipcmessages.h>        // AxWin3 common
13 #include "include/internal.h"
14 #include "include/ipc.h"
15 #include <errno.h>
16
17 #define assert(cnd)     do{if(!(cnd)){_SysDebug("Assertion failed: %s", #cnd);}}while(0)
18
19 #define STATICBUF_SIZE  0x1000
20
21 // === CONSTANTS ===
22 enum eConnectionType
23 {
24         CONNTYPE_NONE,
25         CONNTYPE_SENDMESSAGE,
26         CONNTYPE_IPCPIPE,
27         CONNTYPE_UDP,
28         CONNTYPE_TCP
29 };
30
31 // === GLOBALS ===
32 enum eConnectionType    giConnectionType;
33 int     giConnectionNum;        // FD or PID
34 char    gaAxWin3_int_UDPHeader[] = {5,16,0,0};  // Port 4101
35  int    giAxWin3_int_UDPHeaderLen = sizeof(gaAxWin3_int_UDPHeader);
36 const char      *gsAxWin3_int_ServerDesc;
37 tAxWin3_MessageCallback gAxWin3_MessageCallback;
38
39 // === CODE ===
40 void AxWin3_Connect(const char *ServerDesc)
41 {
42         if( !ServerDesc ) {
43                 ServerDesc = gsAxWin3_int_ServerDesc;
44         }
45         _SysDebug("ServerDesc = %s", ServerDesc);
46         if( !ServerDesc )
47         {
48                 // TODO: Error out
49                 return ;
50         }
51         switch(ServerDesc[0])
52         {
53         case '1': case '2': case '3': case '4': case '5':
54         case '6': case '7': case '8': case '9': case '0':
55                 giConnectionType = CONNTYPE_SENDMESSAGE;
56                 giConnectionNum = atoi(ServerDesc);
57                 if( giConnectionNum == 0 ) {
58                         _SysDebug("Invalid server PID");
59                         exit(-1);
60                 }
61                 break;
62         case 'u':
63                 assert( strncmp(ServerDesc, "udp:", 4) == 0 );
64                 ServerDesc += 4;
65                 _SysDebug("TODO: UDP connection to '%s'", ServerDesc);
66                 // TODO: Open socket and create UDP header
67                 break;
68         case 't':
69                 assert( strncmp(ServerDesc, "tcp:", 4) == 0 );
70                 ServerDesc += 4;
71                 _SysDebug("TODO: TCP connection to '%s'", ServerDesc);
72                 // TODO: Open socket
73                 break;
74         case 'p':
75                 assert( strncmp(ServerDesc, "pipe:", 5) == 0 );
76                 ServerDesc += 5;
77                 giConnectionType = CONNTYPE_IPCPIPE;
78                 giConnectionNum = _SysOpen(ServerDesc, OPENFLAG_READ|OPENFLAG_WRITE);
79                 if( giConnectionNum == -1 ) {
80                         _SysDebug("Cannot open IPC Pipe '%s'", ServerDesc);
81                         exit(-1);
82                 }
83                 break;
84         default:
85                 _SysDebug("Unknown server desc format '%s'", ServerDesc);
86                 exit(-1);
87                 break;
88         }
89 }
90
91 tAxWin3_MessageCallback AxWin3_SetMessageCallback(tAxWin3_MessageCallback Callback)
92 {
93         tAxWin3_MessageCallback old = gAxWin3_MessageCallback;
94         gAxWin3_MessageCallback = Callback;
95         return old;
96 }
97
98 uint32_t AxWin3_int_GetWindowID(tHWND Window)
99 {
100         if(Window)
101                 return Window->ServerID;
102         else
103                 return -1;
104 }
105
106 tAxWin_IPCMessage *AxWin3_int_AllocateIPCMessage(tHWND Window, int Message, int Flags, int ExtraBytes)
107 {
108         tAxWin_IPCMessage       *ret;
109
110         ret = malloc( sizeof(tAxWin_IPCMessage) + ExtraBytes );
111         ret->Flags = Flags;
112         ret->ID = Message;
113         ret->Window = AxWin3_int_GetWindowID(Window);
114         ret->Size = ExtraBytes;
115         return ret;
116 }
117
118 void AxWin3_int_SendIPCMessage(tAxWin_IPCMessage *Msg)
119 {
120          int    size = sizeof(tAxWin_IPCMessage) + Msg->Size;
121         switch(giConnectionType)
122         {
123         case CONNTYPE_SENDMESSAGE:
124                 _SysSendMessage(giConnectionNum, size, Msg);
125                 break;
126         case CONNTYPE_UDP: {
127                 // Create UDP header
128                 char    tmpbuf[giAxWin3_int_UDPHeaderLen + size];
129                 memcpy(tmpbuf, gaAxWin3_int_UDPHeader, giAxWin3_int_UDPHeaderLen);
130                 memcpy(tmpbuf + giAxWin3_int_UDPHeaderLen, Msg, size);
131                 size_t rv = _SysWrite(giConnectionNum, tmpbuf, sizeof(tmpbuf));
132                 if( rv == -1 ) {
133                         _SysDebug("AxWin3 SendIPCMessage: UDP Write Failed %s", strerror(errno));
134                         exit(1);
135                 }
136                 }
137                 break;
138         case CONNTYPE_IPCPIPE:
139         case CONNTYPE_TCP: {
140                 size_t rv = _SysWrite(giConnectionNum, Msg, size);
141                 if( rv != size ) {
142                         _SysDebug("AxWin3 SendIPCMessage: Write Failed %s - sent %i want %i",
143                                 strerror(errno), rv, size);
144                         exit(1);
145                 }
146                 }
147                 break;
148         default:
149                 break;
150         }
151 }
152
153 tAxWin_IPCMessage *AxWin3_int_GetIPCMessage(int nFD, fd_set *fds)
154 {
155          int    len;
156         tAxWin_IPCMessage       *ret = NULL;
157          int    tid;
158         fd_set  local_set;
159         
160         if(!fds)
161                 fds = &local_set;
162
163         if( giConnectionType != CONNTYPE_SENDMESSAGE )
164         {
165                 if(nFD <= giConnectionNum)
166                         nFD = giConnectionNum+1;
167                 FD_SET(giConnectionNum, fds);
168         }
169
170         _SysSelect(nFD, fds, NULL, NULL, NULL, THREAD_EVENT_IPCMSG);
171         
172         // Clear out IPC messages
173         while( (len = _SysGetMessage(&tid, 0, NULL)) )
174         {
175                 if( giConnectionType != CONNTYPE_SENDMESSAGE || tid != giConnectionNum )
176                 {
177                         _SysDebug("%i byte message from %i", len, tid);
178                         // If not, pass the buck (or ignore)
179                         if( gAxWin3_MessageCallback )
180                                 gAxWin3_MessageCallback(tid, len);
181                         else
182                                 _SysGetMessage(NULL, 0, GETMSG_IGNORE);
183                         continue ;
184                 }
185                 
186                 // Using CONNTYPE_SENDMESSAGE and server message has arrived
187                 ret = malloc(len);
188                 if(ret == NULL) {
189                         _SysDebug("malloc() failed, ignoring message");
190                         _SysGetMessage(NULL, 0, GETMSG_IGNORE);
191                         return NULL;
192                 }
193                 _SysGetMessage(NULL, len, ret);
194                 break;
195         }
196
197         if( giConnectionType != CONNTYPE_SENDMESSAGE )
198         {
199                 if( FD_ISSET(giConnectionNum, fds) )
200                 {
201                         char    tmpbuf[STATICBUF_SIZE];
202                         char    *data = tmpbuf;
203                         size_t len = _SysRead(giConnectionNum, tmpbuf, sizeof(tmpbuf));
204                         
205                         if( giConnectionType == CONNTYPE_UDP )
206                         {
207                                 assert(len > giAxWin3_int_UDPHeaderLen);
208                                 len -= giAxWin3_int_UDPHeaderLen;
209                                 data += giAxWin3_int_UDPHeaderLen;
210                         }
211                         assert(len >= sizeof(tAxWin_IPCMessage));
212                         ret = malloc(len);
213                         memcpy(ret, data, len);
214                 }
215         }
216
217         return ret;
218 }
219
220 tAxWin_IPCMessage *AxWin3_int_WaitIPCMessage(int WantedID)
221 {
222         tAxWin_IPCMessage       *msg;
223         for(;;)
224         {
225                 msg = AxWin3_int_GetIPCMessage(0, NULL);
226                 if(msg->ID == WantedID) return msg;
227                 AxWin3_int_HandleMessage( msg );
228         }
229 }
230

UCC git Repository :: git.ucc.asn.au