0

The AT+CENG=2,0 command is giving me this result:

+CENG: 0,"0794,48,00,510,10,53,7944,10,00,36e3,255"

My LAC is 36e3 but what is the type? (Int, Double, byte, string)?

I get this code to translate cell ID and LAC into lat long:

class GMM {
  public static byte[] PostData(int MCC, int MNC, int LAC, int CID) {
    /* The shortCID parameter follows heuristic experiences:
     * Sometimes UMTS CIDs are build up from the original GSM CID (lower 4 hex digits)
     * and the RNC-ID left shifted into the upper 4 digits.
    */
    byte[] pd = new byte[] {
      0x00, 0x0e,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00,
      0x00, 0x00,
      0x00, 0x00,
      0x1b,
      0x00, 0x00, 0x00, 0x00, // Offset 0x11
      0x00, 0x00, 0x00, 0x00, // Offset 0x15
      0x00, 0x00, 0x00, 0x00, // Offset 0x19
      0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, // Offset 0x1f
      0x00, 0x00, 0x00, 0x00, // Offset 0x23
      0x00, 0x00, 0x00, 0x00, // Offset 0x27
      0x00, 0x00, 0x00, 0x00, // Offset 0x2b
      0xff, 0xff, 0xff, 0xff,
      0x00, 0x00, 0x00, 0x00
    };
    Console.WriteLine(pd.Length);
    bool isUMTSCell = ((Int64)CID > 65535);
    if ((Int64)CID > 65536) /* GSM: 4 hex digits, UTMS: 6 hex digits */
      pd[0x1c] = 5;
    else
      pd[0x1c] = 3;
    pd[0x11] = (byte)((MNC >> 24) & 0xFF);
    pd[0x12] = (byte)((MNC >> 16) & 0xFF);
    pd[0x13] = (byte)((MNC >> 8) & 0xFF);
    pd[0x14] = (byte)((MNC >> 0) & 0xFF);
    pd[0x15] = (byte)((MCC >> 24) & 0xFF);
    pd[0x16] = (byte)((MCC >> 16) & 0xFF);
    pd[0x17] = (byte)((MCC >> 8) & 0xFF);
    pd[0x18] = (byte)((MCC >> 0) & 0xFF);
    pd[0x27] = (byte)((MNC >> 24) & 0xFF);
    pd[0x28] = (byte)((MNC >> 16) & 0xFF);
    pd[0x29] = (byte)((MNC >> 8) & 0xFF);
    pd[0x2a] = (byte)((MNC >> 0) & 0xFF);
    pd[0x2b] = (byte)((MCC >> 24) & 0xFF);
    pd[0x2c] = (byte)((MCC >> 16) & 0xFF);
    pd[0x2d] = (byte)((MCC >> 8) & 0xFF);
    pd[0x2e] = (byte)((MCC >> 0) & 0xFF);
    pd[0x1f] = (byte)((CID >> 24) & 0xFF);
    pd[0x20] = (byte)((CID >> 16) & 0xFF);
    pd[0x21] = (byte)((CID >> 8) & 0xFF);
    pd[0x22] = (byte)((CID >> 0) & 0xFF);
    pd[0x23] = (byte)((LAC >> 24) & 0xFF);
    pd[0x24] = (byte)((LAC >> 16) & 0xFF);
    pd[0x25] = (byte)((LAC >> 8) & 0xFF);
    pd[0x26] = (byte)((LAC >> 0) & 0xFF);
    return pd;
  }

  public static string[] GetLatLng() {
    string[] result = new string[2];
    try {
      String url = "http://www.google.com/glm/mmap";
      HttpWebRequest req = (HttpWebRequest)WebRequest.Create(new Uri(url));
      req.Method = "POST";
      int MCC = Convert.ToInt32(510); //actual data
      int MNC = Convert.ToInt32(10); //actual data
      int LAC = Convert.ToInt32(36e3); //actual data - gives error here
      int CID = Convert.ToInt32(7945); //actual data
      byte[] pd = PostData(MCC, MNC, LAC, CID);
      req.ContentLength = pd.Length;
      req.ContentType = "application/binary";
      Stream outputStream = req.GetRequestStream();
      outputStream.Write(pd, 0, pd.Length);
      outputStream.Close();
      HttpWebResponse res = (HttpWebResponse)req.GetResponse();
      byte[] ps = new byte[res.ContentLength];
      int totalBytesRead = 0;
      while (totalBytesRead < ps.Length) {
        totalBytesRead += res.GetResponseStream().Read(
        ps, totalBytesRead, ps.Length - totalBytesRead);
      }
      string r = System.Text.Encoding.UTF8.GetString(ps);
      Console.WriteLine(r);
      if (res.StatusCode == HttpStatusCode.OK) {
        short opcode1 = (short)(ps[0] << 8 | ps[1]);
        byte opcode2 = ps[2];
        int ret_code = (int)((ps[3] << 24) | (ps[4] << 16) | (ps[5] << 8) | (ps[6]));
        if (ret_code == 0) {
          double lat = ((double)((ps[7] << 24) | (ps[8] << 16) | (ps[9] << 8) | (ps[10]))) / 1000000;
          double lon = ((double)((ps[11] << 24) | (ps[12] << 16) | (ps[13] << 8) | (ps[14]))) / 1000000;
          result[0] = lat.ToString();
          result[1] = lon.ToString();
          return result;
        } else {
          return result;
        }
      } else return result;
    }
    catch (Exception ex) {
      result[0] = ex.Message;
      return result;
    }
  }
}
  • 1
    Related: Get Latitude Longitude From AT+CNETSCAN and AT+CENG=2,0. If you don't know what LAC is, why do you care what type it is? – Nick Gammon Aug 12 '17 at 6:58
  • 36e3 looks like a 16-bit hexadecimal value to me. Or it could be engineering notation (36×10³ - unlikely though since it would normally be represented as 3.6e4). What it means though I don't know - the manual would tell you. – Majenko Aug 12 '17 at 9:39
  • @Nick I know what LAC is, but somehow the code above always returns null. So I was wondering if I pass the value incorrectly to google. I pass 14051 as LAC and google gives me nothing, the returning value is null. – Alvin Stefanus Aug 14 '17 at 2:32
1

LAC is "Location Area Code" - the code assigned by the operator to a group of cells that operate as one single broadcast unit.

It is returned to you as a hexadecimal representation of an unsigned 16 bit integer.

To know where the LAC is physically located on the planet you need to look it up in a table. I believe only the operator can give you that information. OS providers like Apple and Google most likely also have access to that data through agreements with operators.

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.