diff --git a/examples/async.py b/examples/async.py index 485212af5..c7d5fa914 100644 --- a/examples/async.py +++ b/examples/async.py @@ -52,6 +52,15 @@ async def send_message_async(state_machine, number, message): async def get_network_info(worker): info = await worker.get_network_info_async() print("NetworkName:", info["NetworkName"]) + + # If NetworkName is empty, look it up in the GSMNetworks database + if not info["NetworkName"] and info["NetworkCode"]: + network_code = info["NetworkCode"] + if network_code in gammu.GSMNetworks: + print(" NetworkName (from DB):", gammu.GSMNetworks[network_code]) + else: + print(" NetworkName (from DB): Unknown network code") + print(" State:", info["State"]) print(" NetworkCode:", info["NetworkCode"]) print(" CID:", info["CID"]) diff --git a/examples/network_info.py b/examples/network_info.py new file mode 100755 index 000000000..ca1743aab --- /dev/null +++ b/examples/network_info.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# vim: expandtab sw=4 ts=4 sts=4: +# +# Copyright © 2003 - 2018 Michal Čihař +# +# This file is part of python-gammu +# +# 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 2 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, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +""" +Example demonstrating how to get network information and look up network names. + +When GetNetworkInfo() returns an empty NetworkName, you can use the +gammu.GSMNetworks dictionary to look up the network name by its NetworkCode. +The NetworkCode is returned by the phone even when NetworkName is empty. + +This is useful because many phones don't return the network name, but the +network code can be looked up in Gammu's network database. +""" + +import sys + +import gammu + + +def get_network_info_with_name(state_machine): + """ + Get network information and look up network name if it's empty. + + The phone returns NetworkCode (e.g., "240 24") even when NetworkName + is empty. We can use gammu.GSMNetworks to look up the network name. + """ + # Get network info from phone + netinfo = state_machine.GetNetworkInfo() + + print("Network Information:") + print("=" * 50) + print(f"Network Code: {netinfo['NetworkCode']}") + print(f"Network Name (from phone): {netinfo['NetworkName']}") + + # If NetworkName is empty, look it up in the GSMNetworks database + if not netinfo["NetworkName"] and netinfo["NetworkCode"]: + network_code = netinfo["NetworkCode"] + if network_code in gammu.GSMNetworks: + network_name = gammu.GSMNetworks[network_code] + print(f"Network Name (from DB): {network_name}") + else: + print(f"Network Name (from DB): Unknown network code '{network_code}'") + + print(f"State: {netinfo['State']}") + print(f"LAC: {netinfo['LAC']}") + print(f"CID: {netinfo['CID']}") + + if "GPRS" in netinfo: + print(f"GPRS: {netinfo['GPRS']}") + + return netinfo + + +def main(): + """Main function to demonstrate network info lookup.""" + # Create state machine + state_machine = gammu.StateMachine() + + # Read configuration from default location (~/.gammurc or /etc/gammurc) + # You can also specify a config file: state_machine.ReadConfig(Filename="gammurc") + state_machine.ReadConfig() + + # Connect to phone + state_machine.Init() + + # Get and display network information with name lookup + get_network_info_with_name(state_machine) + + # You can also explore available networks in the database + print("\n" + "=" * 50) + print("Example: Browsing the GSMNetworks database") + print("=" * 50) + print(f"Total networks in database: {len(gammu.GSMNetworks)}") + + # Show a few example networks + print("\nSome example networks:") + example_codes = ["240 24", "244 05", "310 260", "234 10"] + for code in example_codes: + if code in gammu.GSMNetworks: + print(f" {code}: {gammu.GSMNetworks[code]}") + + +if __name__ == "__main__": + try: + main() + except gammu.GSMError as e: + print(f"Error: {e}") + sys.exit(1) diff --git a/gammu/src/gammu.c b/gammu/src/gammu.c index 0dbfb53d5..c7f35d7a3 100644 --- a/gammu/src/gammu.c +++ b/gammu/src/gammu.c @@ -1819,6 +1819,9 @@ static char StateMachine_GetNetworkInfo__doc__[] = "Gets network information.\n\n" "@return: Hash with information about network (NetworkName, State, NetworkCode, CID and LAC)\n" "@rtype: hash\n" +"@note: NetworkName may be empty if not provided by the phone. In such cases,\n" +" you can look up the network name using NetworkCode in the gammu.GSMNetworks\n" +" dictionary: if network_code in gammu.GSMNetworks: network_name = gammu.GSMNetworks[network_code]\n" ; static PyObject * @@ -1826,6 +1829,7 @@ StateMachine_GetNetworkInfo(StateMachineObject *self, PyObject *args, PyObject * GSM_Error error; GSM_NetworkInfo netinfo; char *buffer, *packet_state; + PyObject *network_name; if (!PyArg_ParseTuple(args, "")) return NULL; @@ -1858,8 +1862,12 @@ StateMachine_GetNetworkInfo(StateMachineObject *self, PyObject *args, PyObject * case GSM_NetworkStatusUnknown: packet_state = "NetworkStatusUnknown"; break; } - return Py_BuildValue("{s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s}", - "NetworkName", netinfo.NetworkName, + network_name = UnicodeStringToPython(netinfo.NetworkName); + if (network_name == NULL) + return NULL; + + return Py_BuildValue("{s:N,s:s,s:s,s:s,s:s,s:s,s:s,s:s,s:s}", + "NetworkName", network_name, "State", buffer, "PacketState", packet_state, "NetworkCode", netinfo.NetworkCode, diff --git a/test/test_asyncworker.py b/test/test_asyncworker.py index 8768cce1a..32243ce02 100644 --- a/test/test_asyncworker.py +++ b/test/test_asyncworker.py @@ -35,7 +35,7 @@ "GPRS": "Attached", "LAC": "B00B", "NetworkCode": "999 99", - "NetworkName": "", + "NetworkName": "GammuT3l", "PacketCID": "DEAD", "PacketLAC": "BEEF", "PacketState": "HomeNetwork", diff --git a/test/test_data.py b/test/test_data.py index b6414ae6e..7d89e60ef 100644 --- a/test/test_data.py +++ b/test/test_data.py @@ -20,6 +20,7 @@ # import unittest +import gammu import gammu.data @@ -30,3 +31,24 @@ def test_connections(self): def test_errors(self): self.assertTrue("ERR_INSTALL_NOT_FOUND" in gammu.data.Errors) self.assertEqual(gammu.data.ErrorNumbers[73], "ERR_NETWORK_ERROR") + + def test_gsm_networks(self): + """Test that GSMNetworks dictionary is available and contains expected data.""" + # GSMNetworks should be a dictionary available from gammu module + self.assertIsInstance(gammu.GSMNetworks, dict) + # Should have at least some networks + self.assertGreater(len(gammu.GSMNetworks), 0) + # Test a known network code (Finland Elisa) + # Network code "244 05" should map to "Elisa" + if "244 05" in gammu.GSMNetworks: + self.assertEqual(gammu.GSMNetworks["244 05"], "Elisa") + + def test_gsm_countries(self): + """Test that GSMCountries dictionary is available and contains expected data.""" + # GSMCountries should be a dictionary available from gammu module + self.assertIsInstance(gammu.GSMCountries, dict) + # Should have at least some countries + self.assertGreater(len(gammu.GSMCountries), 0) + # Test a known country code (Finland) + if "244" in gammu.GSMCountries: + self.assertEqual(gammu.GSMCountries["244"], "Finland")