You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
4.7 KiB

  1. /**
  2. * @file TinyGsmGSMLocation.h
  3. * @author Volodymyr Shymanskyy
  4. * @license LGPL-3.0
  5. * @copyright Copyright (c) 2016 Volodymyr Shymanskyy
  6. * @date Nov 2016
  7. */
  8. #ifndef SRC_TINYGSMGSMLOCATION_H_
  9. #define SRC_TINYGSMGSMLOCATION_H_
  10. #include "TinyGsmCommon.h"
  11. #define TINY_GSM_MODEM_HAS_GSM_LOCATION
  12. template <class modemType>
  13. class TinyGsmGSMLocation {
  14. public:
  15. /*
  16. * GSM Location functions
  17. */
  18. String getGsmLocationRaw() {
  19. return thisModem().getGsmLocationRawImpl();
  20. }
  21. String getGsmLocation() {
  22. return thisModem().getGsmLocationRawImpl();
  23. }
  24. bool getGsmLocation(float* lat, float* lon, float* accuracy = 0,
  25. int* year = 0, int* month = 0, int* day = 0,
  26. int* hour = 0, int* minute = 0, int* second = 0) {
  27. return thisModem().getGsmLocationImpl(lat, lon, accuracy, year, month, day,
  28. hour, minute, second);
  29. };
  30. bool getGsmLocationTime(int* year, int* month, int* day, int* hour,
  31. int* minute, int* second) {
  32. float lat = 0;
  33. float lon = 0;
  34. float accuracy = 0;
  35. return thisModem().getGsmLocation(&lat, &lon, &accuracy, year, month, day,
  36. hour, minute, second);
  37. }
  38. /*
  39. * CRTP Helper
  40. */
  41. protected:
  42. inline const modemType& thisModem() const {
  43. return static_cast<const modemType&>(*this);
  44. }
  45. inline modemType& thisModem() {
  46. return static_cast<modemType&>(*this);
  47. }
  48. /*
  49. * GSM Location functions
  50. * Template is based on SIMCOM commands
  51. */
  52. protected:
  53. // String getGsmLocationImpl() {
  54. // thisModem().sendAT(GF("+CIPGSMLOC=1,1"));
  55. // if (thisModem().waitResponse(10000L, GF("+CIPGSMLOC:")) != 1) { return
  56. // ""; } String res = thisModem().stream.readStringUntil('\n');
  57. // thisModem().waitResponse();
  58. // res.trim();
  59. // return res;
  60. // }
  61. String getGsmLocationRawImpl() {
  62. // AT+CLBS=<type>,<cid>
  63. // <type> 1 = location using 3 cell's information
  64. // 3 = get number of times location has been accessed
  65. // 4 = Get longitude latitude and date time
  66. thisModem().sendAT(GF("+CLBS=1,1"));
  67. // Should get a location code of "0" indicating success
  68. if (thisModem().waitResponse(120000L, GF("+CLBS: ")) != 1) { return ""; }
  69. int8_t locationCode = thisModem().streamGetIntLength(2);
  70. // 0 = success, else, error
  71. if (locationCode != 0) {
  72. thisModem().waitResponse(); // should be an ok after the error
  73. return "";
  74. }
  75. String res = thisModem().stream.readStringUntil('\n');
  76. thisModem().waitResponse();
  77. res.trim();
  78. return res;
  79. }
  80. bool getGsmLocationImpl(float* lat, float* lon, float* accuracy = 0,
  81. int* year = 0, int* month = 0, int* day = 0,
  82. int* hour = 0, int* minute = 0, int* second = 0) {
  83. // AT+CLBS=<type>,<cid>
  84. // <type> 1 = location using 3 cell's information
  85. // 3 = get number of times location has been accessed
  86. // 4 = Get longitude latitude and date time
  87. thisModem().sendAT(GF("+CLBS=4,1"));
  88. // Should get a location code of "0" indicating success
  89. if (thisModem().waitResponse(120000L, GF("+CLBS: ")) != 1) { return false; }
  90. int8_t locationCode = thisModem().streamGetIntLength(2);
  91. // 0 = success, else, error
  92. if (locationCode != 0) {
  93. thisModem().waitResponse(); // should be an ok after the error
  94. return false;
  95. }
  96. // init variables
  97. float ilat = 0;
  98. float ilon = 0;
  99. float iaccuracy = 0;
  100. int iyear = 0;
  101. int imonth = 0;
  102. int iday = 0;
  103. int ihour = 0;
  104. int imin = 0;
  105. int isec = 0;
  106. ilat = thisModem().streamGetFloatBefore(','); // Latitude
  107. ilon = thisModem().streamGetFloatBefore(','); // Longitude
  108. iaccuracy = thisModem().streamGetIntBefore(','); // Positioning accuracy
  109. // Date & Time
  110. iyear = thisModem().streamGetIntBefore('/');
  111. imonth = thisModem().streamGetIntBefore('/');
  112. iday = thisModem().streamGetIntBefore(',');
  113. ihour = thisModem().streamGetIntBefore(':');
  114. imin = thisModem().streamGetIntBefore(':');
  115. isec = thisModem().streamGetIntBefore('\n');
  116. // Set pointers
  117. if (lat != NULL) *lat = ilat;
  118. if (lon != NULL) *lon = ilon;
  119. if (accuracy != NULL) *accuracy = iaccuracy;
  120. if (iyear < 2000) iyear += 2000;
  121. if (year != NULL) *year = iyear;
  122. if (month != NULL) *month = imonth;
  123. if (day != NULL) *day = iday;
  124. if (hour != NULL) *hour = ihour;
  125. if (minute != NULL) *minute = imin;
  126. if (second != NULL) *second = isec;
  127. // Final OK
  128. thisModem().waitResponse();
  129. return true;
  130. }
  131. };
  132. #endif // SRC_TINYGSMGSMLOCATION_H_