user35702: 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;
    }
  }
}


user4143: 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.

35702: <p>The <code>AT+CENG=2,0</code> command is giving me this result:</p>

<blockquote>
  <p>+CENG: 0,"0794,48,00,510,10,53,7944,10,00,36e3,255"</p>
</blockquote>

<p>My LAC is <code>36e3</code> but what is the type? (Int, Double, byte, string)?</p>

<p>I get this code to translate cell ID and LAC into lat long:</p>

<pre><code>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 &gt; 65535);
    if ((Int64)CID &gt; 65536) /* GSM: 4 hex digits, UTMS: 6 hex digits */
      pd[0x1c] = 5;
    else
      pd[0x1c] = 3;
    pd[0x11] = (byte)((MNC &gt;&gt; 24) &amp; 0xFF);
    pd[0x12] = (byte)((MNC &gt;&gt; 16) &amp; 0xFF);
    pd[0x13] = (byte)((MNC &gt;&gt; 8) &amp; 0xFF);
    pd[0x14] = (byte)((MNC &gt;&gt; 0) &amp; 0xFF);
    pd[0x15] = (byte)((MCC &gt;&gt; 24) &amp; 0xFF);
    pd[0x16] = (byte)((MCC &gt;&gt; 16) &amp; 0xFF);
    pd[0x17] = (byte)((MCC &gt;&gt; 8) &amp; 0xFF);
    pd[0x18] = (byte)((MCC &gt;&gt; 0) &amp; 0xFF);
    pd[0x27] = (byte)((MNC &gt;&gt; 24) &amp; 0xFF);
    pd[0x28] = (byte)((MNC &gt;&gt; 16) &amp; 0xFF);
    pd[0x29] = (byte)((MNC &gt;&gt; 8) &amp; 0xFF);
    pd[0x2a] = (byte)((MNC &gt;&gt; 0) &amp; 0xFF);
    pd[0x2b] = (byte)((MCC &gt;&gt; 24) &amp; 0xFF);
    pd[0x2c] = (byte)((MCC &gt;&gt; 16) &amp; 0xFF);
    pd[0x2d] = (byte)((MCC &gt;&gt; 8) &amp; 0xFF);
    pd[0x2e] = (byte)((MCC &gt;&gt; 0) &amp; 0xFF);
    pd[0x1f] = (byte)((CID &gt;&gt; 24) &amp; 0xFF);
    pd[0x20] = (byte)((CID &gt;&gt; 16) &amp; 0xFF);
    pd[0x21] = (byte)((CID &gt;&gt; 8) &amp; 0xFF);
    pd[0x22] = (byte)((CID &gt;&gt; 0) &amp; 0xFF);
    pd[0x23] = (byte)((LAC &gt;&gt; 24) &amp; 0xFF);
    pd[0x24] = (byte)((LAC &gt;&gt; 16) &amp; 0xFF);
    pd[0x25] = (byte)((LAC &gt;&gt; 8) &amp; 0xFF);
    pd[0x26] = (byte)((LAC &gt;&gt; 0) &amp; 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 &lt; 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] &lt;&lt; 8 | ps[1]);
        byte opcode2 = ps[2];
        int ret_code = (int)((ps[3] &lt;&lt; 24) | (ps[4] &lt;&lt; 16) | (ps[5] &lt;&lt; 8) | (ps[6]));
        if (ret_code == 0) {
          double lat = ((double)((ps[7] &lt;&lt; 24) | (ps[8] &lt;&lt; 16) | (ps[9] &lt;&lt; 8) | (ps[10]))) / 1000000;
          double lon = ((double)((ps[11] &lt;&lt; 24) | (ps[12] &lt;&lt; 16) | (ps[13] &lt;&lt; 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;
    }
  }
}
</code></pre>
 4143: <p>LAC is "<a href="https://en.wikipedia.org/wiki/Mobility_management#Location_area" rel="nofollow noreferrer">Location Area Code</a>" - the code assigned by the operator to a group of cells that operate as one single broadcast unit.</p>

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

<p>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.</p>
