Last active
October 23, 2018 18:19
-
-
Save technobly/cea340d13cb7848196b5 to your computer and use it in GitHub Desktop.
Cellular Locate Test Application
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/****************************************************************************** | |
Copyright (c) 2015 Particle Industries, Inc. All rights reserved. | |
This program is free software; you can redistribute it and/or | |
modify it under the terms of the GNU Lesser 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 | |
Lesser General Public License for more details. | |
You should have received a copy of the GNU Lesser General Public | |
License along with this program; if not, see <http://www.gnu.org/licenses/>. | |
****************************************************************************** | |
* | |
* COMPILE from firmware/modules $ | |
* make clean all PLATFORM_ID=10 APPDIR=~/code/fw-apps/cell-locate COMPILE_LTO=n DEBUG_BUILD=y -s program-dfu | |
* | |
* SAMPLE OUTPUT (PRESS 'L or l') | |
* ================= | |
* Hey, you said 'l', so I'm gunna: run Cell Locate... | |
* Waiting for URC ........................................................... | |
* 3/11/2016,21:30:24,LAT:45.7140971,LONG:13.7409172,0,UNCERTAINTY:7335,SPEED:0,0,0,0,0,0,0,MATCHED_COUNT:17 | |
* | |
* https://www.google.com/maps?q=45.7140971,13.7409172 | |
* | |
* | |
* Hey, you said 'l', so I'm gunna: run Cell Locate... | |
* Waiting for URC .................................... | |
* 3/11/2016,21:32:22,LAT:45.7140971,LONG:13.7409172,0,UNCERTAINTY:344,SPEED:0,0,0,2,0,0,0,MATCHED_COUNT:17 | |
* | |
* https://www.google.com/maps?q=45.7140971,13.7409172 | |
* | |
* | |
* Hey, you said 'l', so I'm gunna: run Cell Locate... | |
* Waiting for URC | |
* 3/11/2016,21:32:45,LAT:45.7140971,LONG:13.7409172,0,UNCERTAINTY:804,SPEED:0,0,0,0,0,0,0,MATCHED_COUNT:17 | |
* | |
https://www.google.com/maps?q=45.7140971,13.7409172 | |
*/ | |
#pragma SPARK_NO_PREPROCESSOR | |
#include "application.h" | |
#include "cellular_hal.h" | |
struct MDM_CELL_LOCATE { | |
int day; | |
int month; | |
int year; | |
int hour; | |
int minute; | |
int second; | |
char lat[14]; | |
char lng[14]; | |
int altitude; // only for GNSS positioning | |
int uncertainty; | |
int speed; // only for GNSS positioning | |
int direction; // only for GNSS positioning | |
int vertical_acc; // only for GNSS positioning | |
int sensor_used; // 0: the last fix in the internal database, 2: CellLocate(R) location information | |
int sv_used; // only for GNSS positioning | |
int antenna_status; // only for GNSS positioning | |
int jamming_status; // only for GNSS positioning | |
int count; | |
bool ok; | |
int size; | |
MDM_CELL_LOCATE() | |
{ | |
memset(this, 0, sizeof(*this)); | |
size = sizeof(*this); | |
} | |
}; | |
MDM_CELL_LOCATE _cell_locate; | |
bool displayed_once = false; | |
volatile uint32_t cellTimeout; | |
volatile uint32_t cellTimeStart; | |
// Requires local compile | |
// ALL_LEVEL, TRACE_LEVEL, DEBUG_LEVEL, INFO_LEVEL, WARN_LEVEL, ERROR_LEVEL, PANIC_LEVEL, NO_LOG_LEVEL | |
//SerialDebugOutput debugOutput(9600, ALL_LEVEL); | |
SYSTEM_MODE(AUTOMATIC); | |
void cell_locate_timeout_set(uint32_t timeout_ms) { | |
cellTimeout = timeout_ms; | |
cellTimeStart = millis(); | |
} | |
bool is_cell_locate_timeout() { | |
return (cellTimeout && ((millis()-cellTimeStart) > cellTimeout)); | |
} | |
void cell_locate_timeout_clear() { | |
cellTimeout = 0; | |
} | |
bool is_cell_locate_matched(MDM_CELL_LOCATE& loc) { | |
return loc.ok; | |
} | |
/* Cell Locate Callback */ | |
int _cbLOCATE(int type, const char* buf, int len, MDM_CELL_LOCATE* data) | |
{ | |
if ((type == TYPE_PLUS) && data) { | |
// DEBUG CODE TO SEE EACH LINE PARSED | |
// char line[256]; | |
// strncpy(line, buf, len); | |
// line[len] = '\0'; | |
// Serial.printf("LINE: %s",line); | |
// <response_type> = 1: | |
//+UULOC: <date>,<time>,<lat>,<long>,<alt>,<uncertainty>,<speed>,<direction>, | |
// <vertical_acc>,<sensor_used>,<SV_used>,<antenna_status>,<jamming_status> | |
//+UULOC: 25/09/2013,10:13:29.000,45.7140971,13.7409172,266,17,0,0,18,1,6,3,9 | |
int count = 0; | |
// | |
// TODO: %f was not working for float on LAT/LONG, so opted for capturing strings for now | |
if ( (count = sscanf(buf, "\r\n+UULOC: %d/%d/%d,%d:%d:%d.%*d,%[^,],%[^,],%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", | |
&data->day, | |
&data->month, | |
&data->year, | |
&data->hour, | |
&data->minute, | |
&data->second, | |
data->lat, | |
data->lng, | |
&data->altitude, | |
&data->uncertainty, | |
&data->speed, | |
&data->direction, | |
&data->vertical_acc, | |
&data->sensor_used, | |
&data->sv_used, | |
&data->antenna_status, | |
&data->jamming_status) ) > 0 ) { | |
// UULOC Matched | |
data->count = count; | |
data->ok = true; | |
} | |
} | |
return WAIT; | |
} | |
int cell_locate(MDM_CELL_LOCATE& loc, uint32_t timeout_ms) { | |
loc.count = 0; | |
loc.ok = false; | |
if (RESP_OK == Cellular.command(5000, "AT+ULOCCELL=0\r\n")) { | |
if (RESP_OK == Cellular.command(_cbLOCATE, &loc, timeout_ms, "AT+ULOC=2,2,1,%d,5000\r\n", timeout_ms/1000)) { | |
cell_locate_timeout_set(timeout_ms); | |
if (loc.count > 0) { | |
return loc.count; | |
} | |
return 0; | |
} | |
else { | |
return -2; | |
// Serial.println("Error! No Response from AT+LOC"); | |
} | |
} | |
// else Serial.println("Error! No Response from AT+ULOCCELL"); | |
return -1; | |
} | |
bool cell_locate_in_progress(MDM_CELL_LOCATE& loc) { | |
if (!is_cell_locate_matched(loc) && !is_cell_locate_timeout()) { | |
return true; | |
} | |
else { | |
cell_locate_timeout_clear(); | |
return false; | |
} | |
} | |
bool cell_locate_get_response(MDM_CELL_LOCATE& loc) { | |
// Send empty string to check for URCs that were slow | |
Cellular.command(_cbLOCATE, &loc, 1000, ""); | |
if (loc.count > 0) { | |
return true; | |
} | |
return false; | |
} | |
void cell_locate_display(MDM_CELL_LOCATE& loc) { | |
/* The whole kit-n-kaboodle */ | |
Serial.printlnf("\r\n%d/%d/%d,%d:%d:%d,LAT:%s,LONG:%s,%d,UNCERTAINTY:%d,SPEED:%d,%d,%d,%d,%d,%d,%d,MATCHED_COUNT:%d", | |
loc.month, | |
loc.day, | |
loc.year, | |
loc.hour, | |
loc.minute, | |
loc.second, | |
loc.lat, | |
loc.lng, | |
loc.altitude, | |
loc.uncertainty, | |
loc.speed, | |
loc.direction, | |
loc.vertical_acc, | |
loc.sensor_used, | |
loc.sv_used, | |
loc.antenna_status, | |
loc.jamming_status, | |
loc.count); | |
/* A nice map URL */ | |
Serial.printlnf("\r\nhttps://www.google.com/maps?q=%s,%s\r\n",loc.lat,loc.lng); | |
} | |
// Unclear how much data this uses yet, may want to use a 3rd party SIM to play with this example | |
//STARTUP(cellular_credentials_set("broadband", "", "", NULL)); | |
void setup() | |
{ | |
Serial.begin( 9600 ); | |
} | |
void loop() | |
{ | |
if (Serial.available() > 0) | |
{ | |
char c = Serial.read(); | |
Serial.printf("Hey, you said \'%c\', so I'm gunna: ", c); | |
if (c == 'l' || c == 'L') { | |
Serial.println("run Cell Locate..."); | |
uint32_t timeout = 60000; | |
displayed_once = false; | |
int ret = cell_locate(_cell_locate, timeout); | |
if (ret >= 8) { | |
/* Got the response immediately */ | |
cell_locate_display(_cell_locate); | |
displayed_once = true; | |
} | |
else if (ret == 0) { | |
/* ret == 0, still waiting for the URC | |
* Check for cell locate response, and display it. */ | |
Serial.print("Waiting for URC "); | |
while (cell_locate_in_progress(_cell_locate)) { | |
/* still waiting for URC */ | |
if (cell_locate_get_response(_cell_locate)) { | |
cell_locate_display(_cell_locate); | |
displayed_once = true; | |
} | |
if (!displayed_once) Serial.print("."); | |
} | |
Serial.println(); | |
// Serial.println("Not in progress"); | |
/* We timed out, but maybe we have a response that includes LAT/LONG coords */ | |
if (!displayed_once && _cell_locate.count >= 8) { | |
cell_locate_display(_cell_locate); | |
displayed_once = true; | |
} | |
} | |
else { | |
/* ret == -1 */ | |
Serial.println("Cell Locate Error!"); | |
} | |
} | |
else if (c == 'a' || c == 'A') { | |
// This is required for CellLocate to work properly, but should already be set by default. | |
// Just in case though, here it is for you to use if you are not getting CellLocate results. | |
Serial.print("Reprogram the AssistNow server to u-blox factory default: "); | |
if (RESP_OK == Cellular.command(5000, "AT+UGAOP=\"eval1-les.services.u-blox.com\",46434,1000,0\r\n")) { | |
Serial.println("OK!"); | |
} | |
else { | |
Serial.println("Error!"); | |
} | |
} | |
else { | |
Serial.println("ignore you because you're not speaking my language!"); | |
} | |
while (Serial.available()) Serial.read(); // Flush the input buffer | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment