1 /*
2    Copyright (C) 2004 T. Scott Dattalo
3 
4 This file is part of gpsim.
5 
6 gpsim is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 gpsim is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with gpsim; see the file COPYING.  If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.  */
20 
21 #include "client_interface.h"
22 
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <netdb.h>
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <string.h>
32 
33 #ifdef putc
34 #undef putc
35 #endif
36 
37 #include <gpsim/protocol.h>
38 
39 
Send(const char * msg,int msgLength,char * response,int respLength)40 int ClientSocketInterface::Send(const char *msg, int msgLength,
41 				char *response, int respLength)
42 {
43 
44   if(!sd || !msg || !msgLength ||  !response || !respLength)
45     return 0;
46 
47   if (send(sd, msg, msgLength, 0) == -1) {
48     perror("send");
49     exit(1);
50   }
51 
52   int bytes = recv(sd, response, respLength, 0);
53   if (bytes == -1) {
54     perror("recv");
55     exit(1);
56   }
57 
58   return bytes;
59 }
60 
61 //========================================================================
SendCmd(const char * cmd)62 bool ClientSocketInterface::SendCmd(const char *cmd)
63 {
64   if(cmd) {
65 
66     char response[256];
67 
68     int len = Send(cmd, strlen(cmd), response, sizeof(response));
69 
70     if(len && len <sizeof(response))
71       response[len] = 0;
72 
73     if(len)
74       return true;
75   }
76 
77   return false;
78 }
79 
80 //========================================================================
Send()81 void ClientSocketInterface::Send()
82 {
83   printf("Send sock=%d data:%s\n",sd,p->txBuff());
84   if (send(sd, p->txBuff(), p->txBytesBuffered(), 0) == -1) {
85     perror("send");
86     exit(1);
87   }
88 
89   int bytes= recv(sd, p->rxBuff(), p->rxSize(), 0);
90 
91   if (bytes  == -1) {
92     perror("recv");
93     exit(1);
94   }
95 
96   p->rxTerminate(bytes);
97 
98   printf("Send sock=%d rx data:%s\n",sd,p->rxBuff());
99 
100 }
101 
102 //========================================================================
Receive()103 const char *ClientSocketInterface::Receive()
104 {
105   printf("Receive sock=%d data:%s\n",sd,p->txBuff());
106   p->prepare();
107 
108   /*
109   if (send(sd, p->txBuff(), p->txBytesBuffered(), 0) == -1) {
110     perror("send");
111     exit(1);
112   }
113   */
114 
115   int bytes= recv(sd, p->rxBuff(), p->rxSize(), 0);
116 
117   if (bytes  == -1) {
118     perror("recv");
119     exit(1);
120   }
121 
122   p->rxTerminate(bytes);
123 
124   printf("Receive sock=%d rx data:%s\n",sd,p->rxBuff());
125 
126   return p->rxBuff();
127 }
128 
129 //========================================================================
130 //
CreateCallbackLink(guint64 interval)131 unsigned int ClientSocketInterface::CreateCallbackLink(guint64 interval)
132 {
133   p->prepare();
134 
135   p->EncodeObjectType(GPSIM_CMD_CREATE_CALLBACK_LINK);
136   p->EncodeUInt64(interval);
137 
138   Send();
139 
140   unsigned int handle=0;
141 
142   if(p->DecodeHeader() && p->DecodeUInt32(handle) )
143     return handle;
144 
145   return 0;
146 }
147 
CreateLinkUInt32(const char * sym_name)148 unsigned int ClientSocketInterface::CreateLinkUInt32(const char *sym_name)
149 {
150   p->prepare();
151 
152   p->EncodeObjectType(GPSIM_CMD_CREATE_SOCKET_LINK);
153   p->EncodeString(sym_name);
154 
155   Send();
156 
157   unsigned int handle=0;
158 
159   if(p->DecodeHeader() && p->DecodeUInt32(handle) )
160     return handle;
161 
162   return 0;
163 }
164 
RemoveLink(unsigned int handle)165 void ClientSocketInterface::RemoveLink(unsigned int  handle)
166 {
167   if(handle) {
168     p->prepare();
169     p->EncodeObjectType(GPSIM_CMD_REMOVE_SOCKET_LINK);
170     p->EncodeUInt32(handle);
171     Send();
172   }
173 
174 }
175 
QueryLinkUInt32(unsigned int handle,unsigned int & i)176 bool ClientSocketInterface::QueryLinkUInt32(unsigned int  handle, unsigned int &i)
177 {
178   if(handle) {
179     p->prepare();
180     p->EncodeObjectType(GPSIM_CMD_QUERY_SOCKET_LINK);
181     p->EncodeUInt32(handle);
182     Send();
183     if(p->DecodeHeader() && p->DecodeUInt32(i))
184       return true;
185   }
186   return false;
187 }
188 
WriteToLinkUInt32(unsigned int handle,unsigned int val)189 void ClientSocketInterface::WriteToLinkUInt32(unsigned int  handle, unsigned int val)
190 {
191   if(handle) {
192     p->prepare();
193     p->EncodeObjectType(GPSIM_CMD_WRITE_TO_SOCKET_LINK);
194     p->EncodeUInt32(handle);
195     p->EncodeUInt32(val);
196     Send();
197   }
198 }
199 
QuerySymbolUInt32(const char * sym_name,unsigned int & i)200 bool ClientSocketInterface::QuerySymbolUInt32(const char *sym_name, unsigned int &i)
201 {
202   if(sym_name) {
203     p->prepare();
204     p->EncodeObjectType(GPSIM_CMD_QUERY_SYMBOL);
205     p->EncodeString(sym_name);
206     p->txTerminate();
207     Send();
208 
209     if(p->DecodeHeader() && p->DecodeUInt32(i))
210       return true;
211   }
212 
213   return false;
214 }
215 
WriteSymbolUInt32(const char * sym_name,unsigned int v)216 bool ClientSocketInterface::WriteSymbolUInt32(const char *sym_name, unsigned int v)
217 {
218   if(sym_name) {
219     p->prepare();
220     p->EncodeObjectType(GPSIM_CMD_WRITE_TO_SYMBOL);
221     p->EncodeString(sym_name);
222     p->EncodeUInt32(v);
223     p->txTerminate();
224     Send();
225   }
226 }
227 
228 //------------------------------------------------------------------------
ClientSocketInterface(const char * hostname,int port)229 ClientSocketInterface::ClientSocketInterface(const char *hostname, int port)
230 {
231 
232   struct  sockaddr_in sin;
233   struct  sockaddr_in pin;
234   struct  hostent *hp;
235 
236   sd = 0;
237 
238   char        hname_buff[256];
239   const char *hname;
240 
241   if(!hostname) {
242     gethostname(hname_buff, sizeof(hname_buff));
243     hname = hname_buff;
244   } else
245     hname = hostname;
246 
247   if ((hp = gethostbyname(hname)) == 0) {
248     perror("gethostbyname");
249     exit(1);
250   }
251 
252   /* fill in the socket structure with host information */
253   memset(&pin, 0, sizeof(pin));
254   pin.sin_family = AF_INET;
255   pin.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
256   pin.sin_port = htons(port);
257 
258   /* grab an Internet domain socket */
259   if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
260     perror("socket");
261     exit(1);
262   }
263 
264   /* connect to PORT on HOST */
265   if (connect(sd,(struct sockaddr *)  &pin, sizeof(pin)) == -1) {
266     perror("connect");
267     exit(1);
268   }
269   printf("connected with socket %d\n",sd);
270   p = new Packet(8192,8192);
271 }
272 
273