def polly_register(phno, syslang=d.fr, msglang=d.fr, channel=d.channel, dest=d.POLLY_GAME, return_request=False, retval=False): echo("\nRegister Parameters:\n\nSystem Language:\t" + syslang + "\nMessage Language:\t" + msglang + "\nChannel:\t\t" + channel + "\n") if retval: if dest == d.POLLY_GAME: return polly_request(phno, syslang, msglang, channel, d.POLLY_GAME_ICCID, d.polly_game_ip, return_request) elif dest == d.POLLY_BROWSE: return polly_request(phno, syslang, msglang, channel, d.POLLY_BROWSE_ICCID, d.polly_browse_ip, return_request) else: if dest == d.POLLY_GAME: spin_register_process(phno, syslang, msglang, channel, d.POLLY_GAME_ICCID, d.polly_game_ip, return_request) if dest == d.POLLY_BROWSE: spin_register_process(phno, syslang, msglang, channel, d.POLLY_BROWSE_ICCID, d.polly_browse_ip, return_request)
def keep_alive(AT): echo(prefix(AT.com) + "Sending keep-alive message to server...") dongle_alive = "0" diag = get_diagnostics(AT) if int(diag[0]) > 0: dongle_alive = "1" dongle_alive = [dongle_alive] + diag + [AT.com] csvecho(msg=dongle_alive, pre="ALIVE", retval=False)
def find_connected_dongle_ports(): proc = subprocess.Popen([defines.cmd_root + defines.cmd_mode], stdout=subprocess.PIPE, shell=True) (out, err) = proc.communicate() out = out.decode('utf-8') ports = {} echo("Searching for COM ports...") echo(out) out = out.split("\n") for i in range(len(out) - 1): line = out[i] if "COM" in line: com = line.split()[-1].strip(":") ports[com] = [] while line.strip() != "": i += 1 line = out[i] if ":" in line: l = [x.strip() for x in line.split(":")] ports[com].append((l[0], l[1])) # check that the ports point to SIM cards... valid_ports = {} for port in ports.keys(): if port_has_phone_number(port): valid_ports[port] = ports[port] # return the ports map... return valid_ports
def check_matches_expected_response(at_response, delim, splitter): echo(delim + " Response: " + at_response) if delim in at_response: at = [a.strip() for a in at_response.split(splitter)] return (at, True) else: return ("", False)
def init_for_voice(AT): echo(prefix(AT.com) + "Initializing " + AT.com + " for voice calls...") reset(AT) AT.send_at(d.SHOW_OUTPUT) AT.send_at(d.ENABLE_EXTENDED_FORMAT) AT.send_at(d.ENABLE_CALL_LINE_ID) AT.send_at(d.DISABLE_AUTO_ANSWER) AT.send_at(d.DISABLE_PERIODIC_STATUS_MESSAGES)
def initialize_connection(self): if self.phone is None: self.phone = connect(self.com) self.send('ATE1V1') if ("OK" not in self.read()): echo("Couldn't connect to " + self.com + " or port already in use!") return False return True
def get_rssi(AT): resp = AT.send_at(d.GET_SIGNAL_STRENGTH)[0] at = check_matches_expected_response(resp, d.RESP_GET_SIGNAL_STRENGTH, ":") if at[1]: RSSI = at[0][-1].split(',')[0] echo("RSSI: " + RSSI) if len(RSSI) > 2: # hack if something weird happens... get_rssi(AT) return (RSSI, True) else: return ("NO_RSSI", False)
def get_carrier_send(AT, mode=1): AT.send_at(d.CARRIER_TEXT_DISPLAY, log=True) if mode == 2: AT.send_at(d.CARRIER_TEXT_DISPLAY_2, log=True) elif mode == 3: AT.send_at(d.CARRIER_TEXT_DISPLAY_3, log=True) resp = AT.send_at(d.GET_CARRIER_NAME)[0] at = check_matches_expected_response(resp, d.CARRIER_RETURN, '"') if at[1]: carrier = at[0][1].strip() echo("CARRIER: " + carrier) return (carrier, True) else: return ("NO_CARRIER", False)
def get_application(AT): resp = AT.send_at(d.GET_ICCID)[0] at = check_matches_expected_response(resp, d.ICCID, ":") app = d.POLLY_GAME if at[1]: iccid = at[0][-1].split("\n")[0].strip() echo("ICCID: " + iccid) if iccid == d.POLLY_GAME_ICCID: app = d.POLLY_GAME elif iccid == d.POLLY_BROWSE_ICCID: app = d.POLLY_BROWSE echo("APPLICATION: " + app) return (app, True) else: return (app, False)
def polly_request(phno, syslang, msglang, channel, iccid, app_ip, return_request=False): echo("Registering phno=" + phno + " and iccid=" + iccid + " with Polly...") ip = "http://" + app_ip app = "/" + d.app timeofreq = web_request_timestamp() http_request = ip + app + d.script + phno + d.syslang_prefix + syslang + \ d.msglang_prefix + msglang + d.channel_prefix + channel + d.iccid_prefix + iccid + \ d.timeofreq_prefix + timeofreq return send_request(http_request, return_request)
def get_device_state(AT): resp = AT.send_at(d.GET_DEVICE_STATE)[0] at = check_matches_expected_response(resp, d.DEVICE_STATE, ":") vals = [ 'READY', 'UNAVAILABLE', 'UNKNOWN', 'RINGING', 'CALL_IN_PROGRESS', 'ASLEEP' ] if at[1]: try: i = int(at[0][-1].replace('"', '').split(',')[0].split('\n')[0]) state = vals[i] echo("DEVICE STATE: " + state) return (state, True) except Exception: echo("Exception occurred! Call interrupted!") return (vals[4], True ) # in case an incoming call comes while reading this... else: return (vals[2], False)
def hang_up(AT): hangups = [d.HANG_UP_0, d.HANG_UP_1, d.HANG_UP_2, d.HANG_UP_3, d.HANG_UP_4] for hangup in hangups: echo(prefix(AT.com) + "Trying: " + hangup) response = AT.send_at(hangup)[0] echo(prefix(AT.com) + "Response: " + response) send_ok(AT) time.sleep(1) if d.CALL_END_SIGNAL in response: echo("Call terminated!") return True echo( prefix(AT.com) + "\nCould not terminate call using any known AT commands...\nGoogle Voice and Skype are known to have this problem. \nIs the caller using a VOIP service?\n\nAttempting to restart connection..." ) AT.close_connection() send_ok(AT) return False
def port_has_phone_number(port): echo("Examining port " + port + "...") at_mod = AT(port) number = get_sim_number(at_mod) if (number[1]): resp = extract_phone_number(number[0]) if (resp[1]): echo("PORT " + port + " is valid!") echo("PHONE NUMBER: " + str(resp[0])) return True else: return False else: return False
def check_at_response_is_incoming_call(at_response): at = check_matches_expected_response(at_response, d.CALL_ID, '"') if at[1]: echo("\n=========================" "\nOh Boy! An Incoming Call!" "\n=========================\n") phone_num = at[0][1].strip() if len(phone_num): echo("Incoming Phone Number is : " + phone_num) else: echo("Looks like a Skype call. Number is blank.") phone_num = d.skype return (phone_num, True) else: return at
def send_request(http_request, return_request=False): echo("HTTP Request Generated: " + http_request) if return_request: echo("Returning HTTP request to main script for SMS...") return http_request try: wp = urllib2.urlopen( http_request, timeout=d.web_request_timeout).read().decode('utf-8').replace( "<br>", "\n") request_id = d.REQUEST_PENDING if "ID =" in wp: request_id = wp.split("=")[-1].strip() echo("HTTP Response:\n\n" + wp + "\n") echo("ID: " + request_id) return request_id except urllib2.URLError: print("Network unreachable!") backup_failed_request(http_request) return d.REGISTER_FAILED except Exception as e: echo("An Exception occurred!\n" + str(e)) echo(traceback.format_exc()) backup_failed_request(http_request) echo("Moving on...") return d.REGISTER_FAILED
def send_sms(self, recipient, message): self.sms_module.send_message(recipient, message) def clear_buffers(self): if self.phone is not None: self.phone.flushInput() self.phone.flushOutput() def close_connection(self): if self.phone is not None: time.sleep(self.wait) self.clear_buffers() self.phone.close() self.phone = None time.sleep(self.wait) # ====================================================== # if __name__ == "__main__": phone_num = "+19543679247" #phone_num = "+14123133585" # Rahul, lol com = sys.argv[1] # COM port the dongle is connected to, e.g. COM11 at_module = AT(com) echo(at_module.send_at('ATD' + phone_num + ';')) time.sleep(10) echo(at_module.send_at('AT+CHUP')) echo(at_module.send_at('AT')) echo(at_module.send_at('AT+CNUM')) at_module.send_sms(phone_num, 'hello!') at_module.send_sms(phone_num, 'hey!')
def send_delayed_requests(): # file doesn't exist... create. new_pending_requests_log() delayed_reqs = [ l.strip() for l in open(d.log_dir + d.pending_reqs).readlines() ] if not delayed_reqs: echo("Found no new pending requests! All clear...") return True else: echo("Attempting to send delayed requests...") requests_left = [] for req in delayed_reqs: if req.startswith("http://"): echo("Sending request: " + req) time.sleep(d.wait_time) response = send_request(req) if d.REGISTER_FAILED in response: echo("Request failed again: " + req) requests_left.append(req) elif d.REQUEST_PENDING in response or is_number(response): # call vector: # [rssi,carrier,state]+[request_id,com,phone_num,phno,lang,destination] echo("Delayed request successfully sent! Logging request...") open(d.log_dir + d.pending_reqs_fulfilled, "a").write(req + "\n") # ------ HUGE HACK ----- # request = {} request["rssi"] = "0" request["carrier"] = "DELAYED" request["state"] = "DELAYED" request["request_id"] = response request["com"] = "COM?" req = req.split("?")[-1].split("&") for item in req: item = item.split("=") key = item[0] value = item[1] if key == "ph": request["phone_num"] = value request["phno"] = value elif key == "syslang": request["lang"] = value elif key == "iccid": if value == d.POLLY_BROWSE_ICCID: request["destination"] = d.POLLY_BROWSE else: request["destination"] = d.POLLY_GAME return_request = [request["request_id"],request["com"],request["phone_num"],\ request["phno"],request["lang"],request["destination"],\ request["rssi"],request["carrier"],request["state"]] # ------ END HUGE HACK ----- # # log the request! csvecho(return_request, retval=False) else: # Some other shit happened... log again echo( "Failed to register request! Logging the request to try later..." ) requests_left.append(req) # all finished! if requests_left: echo( "Cannot verify that some requests were successfully sent. Re-queueing failed requests..." ) for request_left in requests_left: backup_failed_request(request_left) return False else: # only if everything was successful... echo("All requests sent! Removing " + d.log_dir + d.pending_reqs) os.remove(d.log_dir + d.pending_reqs) return True
def send_sms(AT, recipient, message, from_dongle=False): try: tropo_remote_sms(recipient, message) except Exception as e: echo( prefix(AT.com) + "An Exception occurred while sending SMS!\n" + str(e)) echo(prefix(AT.com) + traceback.format_exc()) echo( prefix(AT.com) + "Attempting to send regular SMS through dongle...\n") time.sleep(d.sms_wait_time) send_ok(AT) send_ok(AT) AT.clear_buffers() echo(prefix(AT.com) + "Initializing " + AT.com + " for SMS...") AT.send_at(d.HIDE_OUTPUT, log=True) AT.send_at(d.ENABLE_SMS_MODE, log=True) AT.send_at(d.DEFINE_SMS_RECIPIENT + '"' + recipient + '"', log=True) AT.send_at(message, log=True) AT.phone.write(bytes([26])) time.sleep(d.sms_wait_time) echo(prefix(AT.com) + "SMS sent! All clear!") send_ok(AT) send_ok(AT) init_for_voice(AT) send_ok(AT) if from_dongle: echo( prefix(AT.com) + "Attempting to send regular SMS through dongle...\n") time.sleep(d.sms_wait_time) send_ok(AT) send_ok(AT) AT.clear_buffers() echo(prefix(AT.com) + "Initializing " + AT.com + " for SMS...") AT.send_at(d.HIDE_OUTPUT, log=True) AT.send_at(d.ENABLE_SMS_MODE, log=True) AT.send_at(d.DEFINE_SMS_RECIPIENT + '"' + recipient + '"', log=True) AT.send_at(message, log=True) AT.phone.write(bytes([26])) time.sleep(d.sms_wait_time) echo(prefix(AT.com) + "SMS sent! All clear!") send_ok(AT) send_ok(AT) init_for_voice(AT) send_ok(AT)
send_sms(at_module, defines.sms_alert_number, defines.sms_alert_message + str(e)) echo(prefix(com) + "Moving on...") continue # ====================================================== # if __name__ == "__main__": ports = find_connected_dongle_ports() # hack!!! #ports = {'COM17' : '115200'} if len(ports.keys()) < 1: echo("No detected COM ports. Try inserting/reinserting the dongle.") sys.exit(0) else: echo("We in business... There's COM ports here!") # Process queue Q = [] # Process delayed requests if defines.try_failed_requests_at_startup: dreqs = Process(target=send_delayed_requests) Q.append(dreqs) dreqs.start() # Spin processes off on the dongle ports for p in ports.keys():
def listen_on_com_port(com): echo("\n" + prefix(com) + "\nProcess started... Listening on " + com + "...\n") at_module = AT(com) echo(prefix(com) + "Setting up dongle for voice calls...") reset(at_module) init_for_voice(at_module) echo( prefix(com) + "Waiting for a call from Godot... Nothing to be done...\n") counter = 0 destination = get_application(at_module)[0] # INFINITE LOOP TIME while True: # ALGORITHM FOR POLLY DONGLE try: # 1.) Poll the Dongle at_response = at_module.poll() # 2.) Check that the response is not empty... if at_response.strip() != "": # 3.) If it's not empty, check if it's from incoming call resp = check_at_response_is_incoming_call(at_response) # 4.) If it's from an incoming call, process number if (resp[1]): # 5.) Set language and country code phone_num = resp[0] processed_phone_num = process_for_guinea(phone_num) phno = processed_phone_num[0] lang = processed_phone_num[1] # 6.) Hang up the call without answering echo(prefix(com) + "Hanging up call from " + phno + "...") if (hang_up(at_module)): echo(prefix(com) + "Hang up successful!") else: echo( prefix(com) + "Hang up unsuccessful! Trying to register caller anyway..." ) # 7.) Register this number for a callback from Polly request_id = "NONE" if not phno == defines.skype: # ------------------------------------------- # return_for_sms = False # hack!!! change if necessary... # ------------------------------------------- # request_id = polly_register( phno, syslang=lang, msglang=lang, dest=destination, return_request=return_for_sms, retval=True) # huge hack!!! if return_for_sms: echo("Sending SMS to " + defines.sms_backup_number) echo("Request to send: " + request_id) send_sms(at_module, defines.sms_backup_number, request_id, from_dongle=True) echo( "Waiting an extra 2 seconds for SMS to complete..." ) time.sleep(2) else: echo( prefix(com) + "Will not register this call due to blank number..." ) # 8.) text the caller to confirm if defines.sms_confirm and not phno == defines.skype: got_call_msg = defines.got_call_sms[destination][lang] echo(prefix(com) + "Texting caller: " + got_call_msg) send_sms(at_module, phno, got_call_msg) # 8a.) Remote Monitor... send update to CMU print("ID: " + str(request_id)) call_vector = get_diagnostics(at_module) extras = [ request_id, com, phone_num, phno, lang, destination ] call_vector = extras + call_vector echo(prefix(com) + "Logging diagnostic vector...") csvecho(call_vector) # 9.) Delay a bit, check that dongle is still functioning, repeat time.sleep(defines.refresh_rate) counter += 1 if counter % 1000 == 0: if counter >= 3000: counter = 0 send_ok(at_module) keep_alive(at_module) check = send_ok(at_module)[0] if check_ok(check): # do NOT echo this to logging... print( prefix(com) + "Yup. Still monitoring port " + com + " for incoming calls...") else: echo( prefix(com) + "Something seems to be wrong... Check OK returned: " + check) # 10.) If an exception occurs, say f**k it for now, keep going... # Also, send an alert SMS! except Exception as e: echo(prefix(com) + "An Exception occurred!\n" + str(e)) echo(prefix(com) + traceback.format_exc()) echo(defines.sms_alert_number + " " + defines.sms_alert_message) send_sms(at_module, defines.sms_alert_number, defines.sms_alert_message + str(e)) echo(prefix(com) + "Moving on...") continue