Newer
Older
/**
* libwlocate - WLAN-based location service
* Copyright (C) 2010-2014 Oxygenic/VWP virtual_worlds(at)gmx.de
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#ifndef ENV_WINDOWS
#include <arpa/inet.h>
#else
#define snprintf _snprintf
#endif
#include "libwlocate.h"
#include "connect.h"
#include "wlan.h"
#include "assert.h"
#include "errno.h"
WLOC_EXT_API int get_position(const char *domain,const struct wloc_req *request,double *lat,double *lon,char *quality,short *ccode)
{
int sock=0,ret,i;
char head[500+1];
char data[500+1];
char responseOK=0;
setlocale(LC_ALL,"C");
sock=tcp_connect_to(domain);
if (sock<=0)
{
printf("Connect error %d\n",errno);
return WLOC_SERVER_ERROR;
}
tcp_set_blocking(sock,0); // set to non-blocking, we do not want to wait endless for a dead connection
data[0]=0;
for (i=0; i<WLOC_MAX_NETWORKS; i++)
{
if (request->bssids[i][0]+request->bssids[i][1]+request->bssids[i][2]+request->bssids[i][3]+request->bssids[i][4]+request->bssids[i][5]>0)
{
//Skip MESH BSSID: 02:CA:FF:EE:BA:BF
if( request->bssids[i][0] == ownBssid[0]
&& request->bssids[i][1] == ownBssid[1]
&& request->bssids[i][2] == ownBssid[2]
&& request->bssids[i][3] == ownBssid[3]
&& request->bssids[i][4] == ownBssid[4]
&& request->bssids[i][5] == ownBssid[5]){
//SKIP
}
else {
snprintf(data + strlen(data), 500 - strlen(data),
"%02X%02X%02X%02X%02X%02X\r\n",
request->bssids[i][0],request->bssids[i][1],request->bssids[i][2],
request->bssids[i][3],request->bssids[i][4],request->bssids[i][5]);
}
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
}
}
snprintf(head,500,
"POST /getpos.php HTTP/1.0\r\nHost: %s\r\nContent-type: application/x-www-form-urlencoded, *.*\r\nContent-length: %d\r\n\r\n",
domain,strlen(data));
ret=tcp_send(sock,head,strlen(head),5000);
ret+=tcp_send(sock,data,strlen(data),5000);
if (ret<(int)(strlen(head)+strlen(data)))
{
tcp_closesocket(sock);
return WLOC_CONNECTION_ERROR;
}
data[0]=0;
for (;;)
{
ret=tcp_recv(sock,head,500,NULL,100);
if (ret>0)
{
char *pos;
int dataFound=0;
snprintf(data,500,"%s%s",data,head);
if (strstr(data,"\r\n"))
{
// one line received at least so check response code
if (!responseOK)
{
if (!strstr(data,"200 OK"))
{
printf("Error: %s\n",data);
tcp_closesocket(sock);
return WLOC_SERVER_ERROR;
}
responseOK=1;
}
if (strstr(data,"result=0"))
{
tcp_closesocket(sock);
return WLOC_LOCATION_ERROR;
}
if (strstr(data,"quality=0"))
{
tcp_closesocket(sock);
return WLOC_LOCATION_ERROR;
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
}
pos=strstr(data,"quality=");
if (pos);
{
pos+=8;
*quality=atoi(pos);
dataFound|=0x0001;
}
pos=strstr(data,"lat=");
if (pos);
{
pos+=4;
*lat=atof(pos);
if (*lat!=0.0) dataFound|=0x0002;
}
pos=strstr(data,"lon=");
if (pos);
{
pos+=4;
*lon=atof(pos);
if (*lon!=0.0) dataFound|=0x0004;
}
if ((dataFound & 0x0007)==0x0007) break; // all required data received
}
}
}
tcp_closesocket(sock);
// this should never happen, the server should send quality values in range 0..99 only
// assert((*quality>=0) && (*quality<=99));
if (*quality<0) *quality=0;
else if (*quality>99) *quality=99;
// end of this should never happen
*ccode=-1;
return WLOC_OK;
}
/** please refer to libwlocate.h for a description of this function! */
WLOC_EXT_API int wloc_get_location(double *lat,double *lon,char *quality,short *ccode)
{
return wloc_get_location_from("openwlanmap.org",lat,lon,quality,ccode);
}
/** please refer to libwlocate.h for a description of this function! */
WLOC_EXT_API int wloc_get_location_from(const char *domain,double *lat,double *lon,char *quality,short *ccode)
{
#ifdef ENV_LINUX
int sock,i,j;
#endif
struct wloc_req request;
int ret=0;
memset((char*)&request,0,sizeof(struct wloc_req));
//#ifdef ENV_LINUX
// for Linux we have some special handling because only root has full access to the WLAN-hardware:
// there a wlocd-daemon may run with root privileges, so we try to connect to it and receive the
// BSSID data from there. Only in case this fails the way via iwtools is used
//sock=tcp_connect_to("localhost");
/* if (sock>0)
{
ret=tcp_recv(sock,(char*)&request,sizeof(struct wloc_req),NULL,7500);
tcp_closesocket(sock);
if (ret==sizeof(struct wloc_req))
{
ret=0;
for (i=0; i<WLOC_MAX_NETWORKS; i++)
{
if (request.bssids[i][0]+request.bssids[i][1]+request.bssids[i][2]+
request.bssids[i][3]+request.bssids[i][4]+request.bssids[i][5]>0) ret++;
}
}
}*/
/*#else
ret=0;
#endif
if (ret==0)
{*/
if (wloc_get_wlan_data(&request)<2)
{
wloc_get_wlan_data(&request); // try two times in case the device was currently used or could not find all networks
// in case of no success request localisation without WLAN data
}
// }
// for (i=0; i<WLOC_MAX_NETWORKS; i++)
// printf("BSSID: %02X:%02X:%02X:%02X:%02X:%02X Signal: %d\n",request.bssids[i][0] & 0xFF,request.bssids[i][1] & 0xFF,request.bssids[i][2] & 0xFF,
// request.bssids[i][3] & 0xFF,request.bssids[i][4] & 0xFF,request.bssids[i][5] & 0xFF,request.signal[i]);
return get_position(domain,&request,lat,lon,quality,ccode);
}