1 /**
2 	\file apps/obex_test_server.c
3 	Server OBEX Commands.
4 	OpenOBEX test applications and sample code.
5 
6 	Copyright (c) 2000, Pontus Fuchs, All Rights Reserved.
7 
8 	OpenOBEX is free software; you can redistribute it and/or modify
9 	it under the terms of the GNU General Public License as
10 	published by the Free Software Foundation; either version 2 of
11 	the License, or (at your option) any later version.
12 
13 	This program is distributed in the hope that it will be useful,
14 	but WITHOUT ANY WARRANTY; without even the implied warranty of
15 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 	GNU General Public License for more details.
17 
18 	You should have received a copy of the GNU General Public
19 	License along with OpenOBEX. If not, see <http://www.gnu.org/>.
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 
26 #include <openobex/obex.h>
27 
28 #include "obex_io.h"
29 #include "obex_test.h"
30 #include "obex_test_server.h"
31 
32 #include <stdio.h>
33 
34 #include <stdlib.h>
35 #include <fcntl.h>
36 #include <string.h>
37 
38 #define TRUE  1
39 #define FALSE 0
40 
41 //
42 //
43 //
put_server(obex_t * handle,obex_object_t * object)44 static void put_server(obex_t *handle, obex_object_t *object)
45 {
46 	obex_headerdata_t hv;
47 	uint8_t hi;
48 	uint32_t hlen;
49 
50 	const uint8_t *body = NULL;
51 	int body_len = 0;
52 	char *name = NULL;
53 
54 	printf("%s()\n", __FUNCTION__);
55 
56 	while (OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen))	{
57 		switch(hi)	{
58 		case OBEX_HDR_BODY:
59 			printf("%s() Found body\n", __FUNCTION__);
60 			body = hv.bs;
61 			body_len = hlen;
62 			break;
63 
64 		case OBEX_HDR_NAME:
65 			printf("%s() Found name\n", __FUNCTION__);
66 			if (name != NULL)
67 				free(name);
68 			name = malloc(hlen / 2);
69 			if (name != NULL) {
70 				if (OBEX_UnicodeToChar((uint8_t *)name, hv.bs, hlen) < 0) {
71 					free(name);
72 					name = NULL;
73 				}
74 			}
75 			break;
76 
77 		default:
78 			printf("%s() Skipped header %02x\n", __FUNCTION__, hi);
79 		}
80 	}
81 	if(!body)	{
82 		printf("Got a PUT without a body\n");
83 		free(name);
84 		return;
85 	}
86 
87 	if(!name) {
88 		name = "OBEX_PUT_Unknown_object";
89 		printf("Got a PUT without a name. Setting name to %s\n", name);
90 		safe_save_file(name, body, body_len);
91 	} else {
92 		safe_save_file(name, body, body_len);
93 		free(name);
94 	}
95 }
96 
97 //
98 //
99 //
get_server(obex_t * handle,obex_object_t * object)100 static void get_server(obex_t *handle, obex_object_t *object)
101 {
102 	uint8_t *buf;
103 
104 	obex_headerdata_t hv;
105 	uint8_t hi;
106 	uint32_t hlen;
107 	int file_size;
108 
109 	char *name = NULL;
110 
111 	printf("%s()\n", __FUNCTION__);
112 
113 	while (OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen))	{
114 		switch(hi)	{
115 		case OBEX_HDR_NAME:
116 			if (name == NULL)
117 				printf("%s() Found name\n", __FUNCTION__);
118 			else
119 				free(name);
120 			name = malloc(hlen / 2);
121 			if (name != NULL) {
122 				if (OBEX_UnicodeToChar((uint8_t *) name, hv.bs, hlen) < 0) {
123 					free(name);
124 					name = NULL;
125 				}
126 			}
127 			break;
128 
129 		default:
130 			printf("%s() Skipped header %02x\n", __FUNCTION__, hi);
131 		}
132 	}
133 
134 	if(!name)	{
135 		printf("%s() Got a GET without a name-header!\n", __FUNCTION__);
136 		OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_FOUND, OBEX_RSP_NOT_FOUND);
137 		return;
138 	}
139 	printf("%s() Got a request for %s\n", __FUNCTION__, name);
140 
141 	buf = easy_readfile(name, &file_size);
142 	if(buf == NULL) {
143 		printf("Can't find file %s\n", name);
144 		OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_FOUND, OBEX_RSP_NOT_FOUND);
145 		free(name);
146 		return;
147 	}
148 
149 	OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
150 	hv.bs = buf;
151 	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hv, file_size, 0);
152 	hv.bq4 = file_size;
153 	OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH, hv, sizeof(uint32_t), 0);
154 	free(name);
155 	free(buf);
156 	return;
157 }
158 
159 //
160 //
161 //
connect_server(obex_t * handle,obex_object_t * object)162 static void connect_server(obex_t *handle, obex_object_t *object)
163 {
164 	obex_headerdata_t hv;
165 	uint8_t hi;
166 	uint32_t hlen;
167 
168 	const uint8_t *who = NULL;
169 	int who_len = 0;
170 	printf("%s()\n", __FUNCTION__);
171 
172 	while (OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen))	{
173 		if(hi == OBEX_HDR_WHO)	{
174 			who = hv.bs;
175 			who_len = hlen;
176 		}
177 		else	{
178 			printf("%s() Skipped header %02x\n", __FUNCTION__, hi);
179 		}
180 	}
181 	if (who_len == 6)	{
182 		if(memcmp("Linux", who, 6) == 0)	{
183 			printf("Weeeha. I'm talking to the coolest OS ever!\n");
184 		}
185 	}
186 	OBEX_ObjectSetRsp(object, OBEX_RSP_SUCCESS, OBEX_RSP_SUCCESS);
187 }
188 
189 //
190 //
191 //
server_request(obex_t * handle,obex_object_t * object,int event,int cmd)192 void server_request(obex_t *handle, obex_object_t *object, int event, int cmd)
193 {
194 	switch(cmd)	{
195 	case OBEX_CMD_CONNECT:
196 		connect_server(handle, object);
197 		break;
198 	case OBEX_CMD_DISCONNECT:
199 		printf("We got a disconnect-request\n");
200 		OBEX_ObjectSetRsp(object, OBEX_RSP_SUCCESS, OBEX_RSP_SUCCESS);
201 		break;
202 	case OBEX_CMD_GET:
203 		/* A Get always fits one package */
204 		get_server(handle, object);
205 		break;
206 	case OBEX_CMD_PUT:
207 		OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
208 		put_server(handle, object);
209 		break;
210 	case OBEX_CMD_SETPATH:
211 		printf("Got a SETPATH request\n");
212 		OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS);
213 		break;
214 	default:
215 		printf("%s() Denied %02x request\n", __FUNCTION__, cmd);
216 		OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_IMPLEMENTED, OBEX_RSP_NOT_IMPLEMENTED);
217 		break;
218 	}
219 	return;
220 }
221 
222 //
223 //
224 //
server_done(obex_t * handle,obex_object_t * object,int obex_cmd,int obex_rsp)225 void server_done(obex_t *handle, obex_object_t *object, int obex_cmd, int obex_rsp)
226 {
227 	struct context *gt;
228 	gt = OBEX_GetUserData(handle);
229 
230 	printf("Server request finished!\n");
231 
232 	switch (obex_cmd) {
233 	case OBEX_CMD_DISCONNECT:
234 		printf("Disconnect done!\n");
235 		OBEX_TransportDisconnect(handle);
236 		gt->serverdone = TRUE;
237 		break;
238 
239 	default:
240 		printf("%s() Command (%02x) has now finished\n", __FUNCTION__, obex_cmd);
241 		break;
242 	}
243 }
244 
245 //
246 //
247 //
server_do(obex_t * handle)248 void server_do(obex_t *handle)
249 {
250 	int ret;
251 	struct context *gt;
252 	gt = OBEX_GetUserData(handle);
253 
254 	gt->serverdone = FALSE;
255 	while(!gt->serverdone) {
256 		ret = OBEX_HandleInput(handle, 60);
257 		if(ret < 0) {
258 			printf("Error while doing OBEX_HandleInput()\n");
259 			break;
260 		} else if (ret == 0) {
261 			printf("Timeout while doing OBEX_HandleInput()\n");
262 			break;
263 		} else {
264 			printf("OBEX_HandleInput() returned %d\n",ret);
265 		}
266 	}
267 }
268