static void gn_atem_answer_phone(void) { /* For now we'll also initialise the datapump + rlp code again */ dp_Initialise(PtyRDFD, PtyWRFD); data.call_notification = dp_CallPassup; gn_sm_functions(GN_OP_SetCallNotification, &data, sm); data.call_info->call_id = IncomingCallNo; gn_sm_functions(GN_OP_AnswerCall, &data, sm); CommandMode = false; }
static void gn_atem_hangup_phone(void) { if (IncomingCallNo > 0) { rlp_user_request_set(Disc_Req, true); gn_sm_loop(10, sm); } if (IncomingCallNo > 0) { data.call_info->call_id = IncomingCallNo; gn_sm_functions(GN_OP_CancelCall, &data, sm); IncomingCallNo = -1; } dp_Initialise(PtyRDFD, PtyWRFD); }
/* If initialised in debug mode, stdin/out is used instead of ptys for interface. */ int gn_vm_initialise(const char *iname, const char *bindir, int debug_mode, int GSMInit) { static struct gn_statemachine State; sm = &State; queue.n = 0; queue.head = 0; queue.tail = 0; CommandMode = true; if (debug_mode == true) { UseSTDIO = true; } else { UseSTDIO = false; } if (GSMInit) { dprintf("Initialising GSM\n"); if (gn_cfg_phone_load(iname, sm) != GN_ERR_NONE) return false; if ((VM_GSMInitialise(sm) != GN_ERR_NONE)) { fprintf (stderr, _("gn_vm_initialise - VM_GSMInitialise failed!\n")); return (false); } } GSMInit = false; if (VM_PtySetup(bindir) < 0) { fprintf (stderr, _("gn_vm_initialise - VM_PtySetup failed!\n")); return (false); } if (gn_atem_initialise(PtyRDFD, PtyWRFD, sm) != true) { fprintf (stderr, _("gn_vm_initialise - gn_atem_initialise failed!\n")); return (false); } if (dp_Initialise(PtyRDFD, PtyWRFD) != true) { fprintf (stderr, _("gn_vm_initialise - dp_Initialise failed!\n")); return (false); } return (true); }
/* If initialised in debug mode, stdin/out is used instead of ptys for interface. */ bool gn_vm_initialise(const char *iname, bool GSMInit) { static struct gn_statemachine State; sm = &State; queue.n = 0; queue.head = 0; queue.tail = 0; CommandMode = true; if (GSMInit) { dprintf("Initialising GSM\n"); if (gn_cfg_phone_load(iname, sm) != GN_ERR_NONE) return false; if ((VM_GSMInitialise(sm) != GN_ERR_NONE)) { fprintf (stderr, _("gn_vm_initialise - VM_GSMInitialise failed!\n")); return (false); } } GSMInit = false; if (VM_PtySetup() < 0) { fprintf (stderr, _("gn_vm_initialise - VM_PtySetup failed!\n")); return (false); } if (gn_atem_initialise(sm) != true) { fprintf (stderr, _("gn_vm_initialise - gn_atem_initialise failed!\n")); return (false); } if (dp_Initialise() != true) { fprintf (stderr, _("gn_vm_Initialise - dp_Initialise failed!\n")); return (false); } return (true); }
/* Parser for standard AT commands. cmd_buffer must be null terminated. */ void gn_atem_at_parse(char *cmd_buffer) { char *buf; int regno, val; char str[256]; if (!cmd_buffer[0]) return; if (strncasecmp (cmd_buffer, "AT", 2) != 0) { gn_atem_modem_result(MR_ERROR); return; } for (buf = &cmd_buffer[2]; *buf;) { switch (toupper(*buf)) { case 'Z': /* Reset modem */ buf++; switch (gn_atem_num_get(&buf)) { case -1: case 0: /* reset and load stored profile 0 */ case 1: /* reset and load stored profile 1 */ gn_atem_hangup_phone(); gn_atem_registers_init(); break; default: gn_atem_modem_result(MR_ERROR); return; } break; case 'A': /* Answer call */ buf++; gn_atem_answer_phone(); return; break; case 'D': /* Dial Data :-) */ /* FIXME - should parse this better */ /* For now we'll also initialise the datapump + rlp code again */ dp_Initialise(PtyRDFD, PtyWRFD); buf++; if (toupper(*buf) == 'T' || toupper(*buf) == 'P') buf++; while (*buf == ' ') buf++; data.call_notification = dp_CallPassup; gn_sm_functions(GN_OP_SetCallNotification, &data, sm); snprintf(data.call_info->number, sizeof(data.call_info->number), "%s", buf); if (ModemRegisters[S35] == 0) data.call_info->type = GN_CALL_DigitalData; else data.call_info->type = GN_CALL_NonDigitalData; data.call_info->send_number = GN_CALL_Default; CommandMode = false; if (gn_sm_functions(GN_OP_MakeCall, &data, sm) != GN_ERR_NONE) { CommandMode = true; dp_CallPassup(GN_CALL_RemoteHangup, NULL, NULL, NULL); } else { IncomingCallNo = data.call_info->call_id; gn_sm_loop(10, sm); } return; break; case 'H': /* Hang Up */ buf++; switch (gn_atem_num_get(&buf)) { case -1: case 0: /* hook off the phone */ gn_atem_hangup_phone(); break; case 1: /* hook on the phone */ break; default: gn_atem_modem_result(MR_ERROR); return; } break; case 'S': /* Change registers */ buf++; regno = gn_atem_num_get(&buf); if (regno < 0 || regno >= MAX_MODEM_REGISTERS) { gn_atem_modem_result(MR_ERROR); return; } if (*buf == '=') { buf++; val = gn_atem_num_get(&buf); if (val < 0 || val > 255) { gn_atem_modem_result(MR_ERROR); return; } ModemRegisters[regno] = val; } else if (*buf == '?') { buf++; snprintf(str, sizeof(str), "%d\r\n", ModemRegisters[regno]); gn_atem_string_out(str); } else { gn_atem_modem_result(MR_ERROR); return; } break; case 'E': /* E - Turn Echo on/off */ buf++; switch (gn_atem_num_get(&buf)) { case -1: case 0: ModemRegisters[REG_ECHO] &= ~BIT_ECHO; break; case 1: ModemRegisters[REG_ECHO] |= BIT_ECHO; break; default: gn_atem_modem_result(MR_ERROR); return; } break; case 'Q': /* Q - Turn Quiet on/off */ buf++; switch (gn_atem_num_get(&buf)) { case -1: case 0: ModemRegisters[REG_QUIET] &= ~BIT_QUIET; break; case 1: ModemRegisters[REG_QUIET] |= BIT_QUIET; break; default: gn_atem_modem_result(MR_ERROR); return; } break; case 'V': /* V - Turn Verbose on/off */ buf++; switch (gn_atem_num_get(&buf)) { case -1: case 0: ModemRegisters[REG_VERBOSE] &= ~BIT_VERBOSE; break; case 1: ModemRegisters[REG_VERBOSE] |= BIT_VERBOSE; break; default: gn_atem_modem_result(MR_ERROR); return; } break; case 'X': /* X - Set verbosity of the result messages */ buf++; switch (gn_atem_num_get(&buf)) { case -1: case 0: val = 0x00; break; case 1: val = 0x40; break; case 2: val = 0x50; break; case 3: val = 0x60; break; case 4: val = 0x70; break; case 5: val = 0x10; break; default: gn_atem_modem_result(MR_ERROR); return; } ModemRegisters[S22] = (ModemRegisters[S22] & 0x8f) | val; break; case 'I': /* I - info */ buf++; switch (gn_atem_num_get(&buf)) { case -1: case 0: /* terminal id */ snprintf(str, sizeof(str), "%d\r\n", ModemRegisters[39]); gn_atem_string_out(str); break; case 1: /* serial number (IMEI) */ snprintf(str, sizeof(str), "%s\r\n", imei); gn_atem_string_out(str); break; case 2: /* phone revision */ snprintf(str, sizeof(str), "%s\r\n", revision); gn_atem_string_out(str); break; case 3: /* modem revision */ gn_atem_string_out("gnokiid " VERSION "\r\n"); break; case 4: /* OEM string */ snprintf(str, sizeof(str), "%s %s\r\n", manufacturer, model); gn_atem_string_out(str); break; default: gn_atem_modem_result(MR_ERROR); return; } break; /* Handle AT* commands (Nokia proprietary I think) */ case '*': buf++; if (!strcasecmp(buf, "NOKIATEST")) { gn_atem_modem_result(MR_OK); /* FIXME? */ return; } else { if (!strcasecmp(buf, "C")) { gn_atem_modem_result(MR_OK); Parser = gn_atem_sms_parse; return; } } break; /* + is the precursor to another set of commands */ case '+': buf++; switch (toupper(*buf)) { case 'C': buf++; /* Returns true if error occured */ if (gn_atem_command_plusc(&buf) == true) { gn_atem_modem_result(MR_ERROR); return; } break; case 'G': buf++; /* Returns true if error occured */ if (gn_atem_command_plusg(&buf) == true) { gn_atem_modem_result(MR_ERROR); return; } break; default: gn_atem_modem_result(MR_ERROR); return; } break; /* # is the precursor to another set of commands */ case '#': buf++; /* Returns true if error occured */ if (gn_atem_command_diesis(&buf) == true) { gn_atem_modem_result(MR_ERROR); return; } break; default: gn_atem_modem_result(MR_ERROR); return; } } gn_atem_modem_result(MR_OK); }