http://marcin-wiacek.fkn.pl/english/zips/mygnokii.tar.gz
[gnokii.git] / mgnetd / mg_demo_client / mg_net_api.c
1 /*
2    MYGNOKII net_api 
3    Version 0.03 07.02.2002
4    <ralf@mythelen.de>
5         */
6
7 #include <sys/types.h>
8 #include <sys/socket.h>
9 #include <sys/errno.h>
10 #include <netinet/in.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <signal.h>
14 #include <netdb.h>
15 #include <unistd.h>
16 #include "mg_net_api.h"
17
18
19 /* globals */
20 static int mg_s;                                /* socket descriptor */
21 static struct sockaddr_in mg_myaddr_in;         /* for local socket address */
22 static struct sockaddr_in mg_servaddr_in;       /* for server socket address */
23 static char mg_password[8];                     /* passwd for udp-requsts */
24
25 /*
26  *                      H A N D L E R
27  *
28  *      This routine is the signal handler for the alarm signal.
29  *      It simply re-installs itself as the handler and returns.
30  */
31 void handler()
32 {
33         signal(SIGALRM, handler);
34 }
35
36 /* Send the request to the server. */
37 /* and wait for response           */
38 static int send_rq(MG_api_request *rq)
39 {
40 int ret;
41
42 strncpy(rq->passwd,mg_password,8);
43
44 if (sendto (mg_s, rq, sizeof(*rq), 0, (struct sockaddr *) &mg_servaddr_in,
45                         sizeof(struct sockaddr_in)) == -1) {
46         return(-1);
47         }
48
49
50   /* Set up alarm signal handler. */
51 signal(SIGALRM, handler);
52
53   /* Set up a timeout so I don't hang in case the packet
54    * gets lost.  After all, UDP does not guarantee
55    * delivery.
56    */
57 alarm(5);
58
59   /* Wait for the reply to come in.  We assume that
60    * no messages will come from any other source,
61    * so that we do not need to do a recvfrom nor
62    * check the responder's address.
63    */   
64
65 /* RTH FIXME: TIMEOUT DONT WORK !! */
66 ret = recv (mg_s, rq, sizeof(*rq), 0);
67 switch (ret) {
68         case EINTR:
69          /* Alarm went off and aborted the receive. */
70          alarm(0);
71          return(MG_ERROR_TIMEOUT);
72          break;
73
74         default:
75          alarm(0);
76          return(ret);
77          break;
78         }
79 }
80
81 int mg_exit(void)
82 {
83 int ret;
84 MG_api_request rq;
85
86 rq.cmd = MG_EXIT;
87
88 ret = send_rq(&rq);
89
90 if (ret < 0) 
91         return(ret);
92 else return(rq.cmd);
93
94 }
95
96 int mg_version(MG_rq_version *version)
97 {
98 int ret;
99 MG_api_request rq;
100
101 rq.cmd = MG_VERSION;
102
103 ret = send_rq(&rq);
104
105 if (ret < 0) 
106         return(ret);
107 else
108         {
109         memcpy(version, rq.buffer, sizeof(*version));
110         return(rq.cmd);
111         }
112 }
113
114 int mg_identify(MG_rq_identify *ident)
115 {
116 int ret;
117 MG_api_request rq;
118
119 rq.cmd = MG_IDENTIFY;
120
121 ret = send_rq(&rq);
122
123 if (ret < 0) 
124         return(ret);
125 else
126         {
127         memcpy(ident, rq.buffer, sizeof(*ident));
128         return(rq.cmd);
129         }
130 }
131
132 int mg_memorystatus(MG_rq_memorystatus *stats)
133 {
134 int ret;
135 MG_api_request rq;
136
137 rq.cmd = MG_MEMORYSTATUS;
138 memcpy(rq.buffer, stats, sizeof(*stats));
139
140 ret = send_rq(&rq);
141
142 if (ret < 0) 
143         return(ret);
144 else
145         {
146         memcpy(stats, rq.buffer, sizeof(*stats));
147         return(rq.cmd);
148         }
149 }
150
151 int mg_get_memory_location(MG_rq_phonebook_location *rph)
152 {
153 int ret;
154 MG_api_request rq;
155
156 rq.cmd = MG_GET_MEMORY_LOCATION;
157 memcpy(rq.buffer, rph, sizeof(*rph));
158
159 ret = send_rq(&rq);
160
161 if (ret < 0) 
162         return(ret);
163 else
164         {
165         memcpy(rph, rq.buffer, sizeof(*rph));
166         return(rq.cmd);
167         }
168 }
169
170 int mg_write_phonebook_location(MG_rq_phonebook_location *wph)
171 {
172 int ret;
173 MG_api_request rq;
174
175 rq.cmd = MG_WRITE_PHONEBOOK_LOCATION;
176 memcpy(rq.buffer, wph, sizeof(*wph));
177
178 ret = send_rq(&rq);
179
180 if (ret < 0) 
181         return(ret);
182 else
183         {
184         memcpy(wph, rq.buffer, sizeof(*wph));
185         return(rq.cmd);
186         }
187 }
188
189 int mg_delete_phonebook_location(MG_rq_phonebook_location *dph)
190 {
191 int ret;
192 MG_api_request rq;
193
194 rq.cmd = MG_DELETE_PHONEBOOK_LOCATION;
195 memcpy(rq.buffer, dph, sizeof(*dph));
196
197 ret = send_rq(&rq);
198
199 if (ret < 0) 
200         return(ret);
201 else
202         {
203         memcpy(dph, rq.buffer, sizeof(*dph));
204         return(rq.cmd);
205         }
206 }
207
208 int mg_send_sms(MG_rq_send_sms *sms)
209 {
210 int ret;
211 MG_api_request rq;
212
213 rq.cmd = MG_SEND_SMS;
214 memcpy(rq.buffer, sms, sizeof(*sms));
215
216 ret = send_rq(&rq);
217
218 if (ret < 0) 
219         return(ret);
220 else
221         {
222         memcpy(sms, rq.buffer, sizeof(*sms));
223         return(rq.cmd);
224         }
225 }
226
227
228 /*
229         mg_init
230         Input: Hostname of mygnokii-server
231         Output: connected udp-port on success, else -1 
232 */
233 int mg_init(char *hostname, char *passwd)
234 {
235
236 struct hostent *hp;             /* pointer to host info for nameserver host */
237 struct servent *sp;             /* pointer to service information */
238
239 /* set password */
240 strncpy(mg_password,passwd,8);  
241
242 /* clear out address structures */
243 memset ((char *)&mg_myaddr_in, 0, sizeof(struct sockaddr_in));
244 memset ((char *)&mg_servaddr_in, 0, sizeof(struct sockaddr_in));
245
246 /* Set up the server address. */
247 mg_servaddr_in.sin_family = AF_INET;
248
249 /* Get the host information for the server's hostname that the
250  * user passed in.
251  */
252 hp = gethostbyname (hostname);
253 if (hp == NULL) {
254          return(1);
255         }
256
257 mg_servaddr_in.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
258 /* Find the information for the "example" server
259  * in order to get the needed port number.
260  */
261 sp = getservbyname ("mygnokii", "udp");
262 if (sp == NULL) {
263        /* not found -> use default port 50963 */
264         mg_servaddr_in.sin_port = htons(50963);
265         }
266 else mg_servaddr_in.sin_port = sp->s_port;
267                 
268 /* Create the socket. */
269 mg_s = socket (AF_INET, SOCK_DGRAM, 0);
270 if (mg_s == -1) {
271          return(-1);
272         }
273
274         /* Bind socket to some local address so that the
275          * server can send the reply back.  A port number
276          * of zero will be used so that the system will
277          * assign any available port number.  An address
278          * of INADDR_ANY will be used so we do not have to
279          * look up the internet address of the local host.
280          */
281 mg_myaddr_in.sin_family = AF_INET;
282 mg_myaddr_in.sin_port = 0;
283 mg_myaddr_in.sin_addr.s_addr = INADDR_ANY;
284 if (bind(mg_s, (struct sockaddr *) &mg_myaddr_in, sizeof(struct sockaddr_in)) == -1) {
285                 return(-1);
286         }
287
288 /* return portnumber */
289 return(mg_servaddr_in.sin_port);
290
291 }
292