Skip to content

Instantly share code, notes, and snippets.

@wtv-411
Last active June 11, 2023 18:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wtv-411/6c3e4b4cfce495d8cc56fe634b2e35c5 to your computer and use it in GitHub Desktop.
Save wtv-411/6c3e4b4cfce495d8cc56fe634b2e35c5 to your computer and use it in GitHub Desktop.
De-tokenized TellyScript code originally generated for a WebTV (Classic) box
/*
* This file contains a de-tokenized version of a TellyScript, a C-like language,
* generated by the WebTV/MSN TV service. The script in question was originally generated for
* an original WebTV Classic box (bf0/FCS) on May 27th, 1998, and was later decompiled using
* Andy McFadden's "detok" tool (https://gist.github.com/fadden/09b581dbb047945d3119048dc05e8bea)
* and cleaned up by me (wtv-411). The original, "compiled" version can be found as
* "bf0app_WTV_19980527.tok" on Archive.org here: https://archive.org/details/wtv-tellyscripts
*
* TellyScript is a scripting language designed by WebTV Networks. Its main purpose was
* to provide local phone numbers to be used for dial-up access by the WebTV and MSN TV
* line of internet set-top boxes (with a couple exceptions). TellyScript was designed by
* Andy Rubin and was based off of a scripting language he had previously written
* in college. There are only a couple WebTV/MSN TV clients known to not support the
* original TellyScript format. UltimateTV, a Windows CE-based satellite DVR built on WebTV
* technology, uses a variant of the format named DialScript, and the MSN TV 2 forgoes
* using TellyScript entirely.
*
* TellyScript is essentially a watered-down version of C and was designed to have
* the flexibility of a general programming language to have better control
* over a WebTV box's modem and the overall dialing process. Considering that the
* original WebTV boxes only had 2MB of ROM space, the TellyScript compiler couldn't
* support some features or data types that the original C language has, such as switch,
* bitwise OR, AND, and XOR, and the ability to initialize global variables. More information
* on the format can be found in the code of fadden's detok tool and here:
* https://wiki.webtv.zone/mediawiki/index.php/TellyScript
*
* All work from me involved renaming the appropriate variables and functions
* and adding comments to make the de-tokenized code more readable. Most of the
* variables were later swapped out for the names used in the original .tsf files used by
* the WebTV service to build TellyScripts (currently not available publicly to my knowledge).
* This code is being provided publicly for educational purposes, as it provides
* good insight into how TellyScripts work and interact with the WebTV/MSN TV hardware.
*
* Do note that this code cannot be compiled with a standard compiler, and would've
* been tokenized with a specialized TellyScript compiler on the WebTV service.
* A modern day equivalent of this has not been made yet as of writing. The newlines
* retained in the tokenized script will be kept in this code file for posterity.
*/
/* START OF DETOKENIZED TELLYSCRIPT */
int gDTERate; /* connection stats, set by ParseResult() */
int gDCERate;
int gProtocol;
int gCompression;
int gConnected; /* set to 1 by ParseResult if we're considered connected */
int gUsingOpenISP; /* are we an OpenISP script? */
int gNVRAMMayBeInvalid; /* was the script sent down for a brain-dead download?*/
WinkDTR() /* WNI hack to make the modem work properly. Fiddles with DTR. */
{
setdtr(0);
delay(30);
setdtr(1);
delay(30);
return 0;
}
StrLen(char *source)
{
int count = 0;
while (*source++)
count++;
return count;
}
StrnCpy(char* dstStr, char* srcStr, int count) // WNI drop-in replacement for strncpy
{
while (*srcStr) {
if (!count--) {
break;
}
*dstStr++ = *srcStr++;
}
if (count > 0)
*dstStr = 0;
return 0;
}
OStrChr(char *source, int value)
{
char *orig = source;
while (*source != '\0') {
if (*source == value) {
return source - orig;
}
source++;
}
return -1;
}
SetDialingProgress(char *progressText, int percentage)
{
setprogresstext(progressText);
setprogresspercentage(percentage);
setprogressdirty(1);
return 0;
}
// GetPhoneSettings - takes in int pointer as argument, returns pointer to phone settings buffer and sets int pointer to FONE version
GetPhoneSettings(int *pSettingsVersion)
{
char *fonePtr;
int *foneLength;
int *magic;
int *rom_size = 0xbf00000c; // Pointer @ 0xbf00000c that reads the ROM size of the WebTV/MSN TV box's
// boot(?) ROM defined in its header
int *foneAddrEnd;
*pSettingsVersion = 0;
if (version() >= 9 || gNVRAMMayBeInvalid) { // is version >= 9 or is our NVRAM corrupted?
*pSettingsVersion = version();
return getphonesettings(); // return data from built-in getphonesettings function
}
if (*rom_size == 0x80000) { // is the box ROM a 2MB rom?
fonePtr = 0xbf1fc000; // set FONE pointer to address 0xbf1fc000
foneAddrEnd = 0xbf200000; // set pointer of end of data to address 0xbf200000
} else if (*rom_size == 0x100000) { // else, if it's a 4MB rom...
fonePtr = 0xbf3fc000; // set the FONE pointer addresses accordingly
foneAddrEnd = 0xbf400000;
} else {
printf("TellyScript: couldn't determine size of ROM!");
return 0;
}
fonePtr = fonePtr + 16; // advance 16 bytes in FONE data memory. skips past NVRAM header
while ((fonePtr + 9) < foneAddrEnd) { // read until end of ROM area
foneLength = fonePtr;
magic = fonePtr + 4; // set pointer to magic bytes 4 bytes after the FONE pointer
if (*magic == 0x464f4e45/*FONE*/) {
if (*foneLength == 105) {
*pSettingsVersion = 5;
} else if (*foneLength == 172) {
*pSettingsVersion = 8;
} else if (*foneLength == 336) {
*pSettingsVersion = 9;
} else if (*foneLength == 344) {
*pSettingsVersion = 11;
} else {
*pSettingsVersion = version();
}
printf("TellyScript: FONE @ %x, len=%d, version=%d",
fonePtr + 8, *foneLength, *pSettingsVersion);
if (*pSettingsVersion == version()) {
return getphonesettings();
} else {
return fonePtr + 8;
}
}
fonePtr = fonePtr + *foneLength + 8; /* advance pointer in FONE by the length plus 8 */
fonePtr = fonePtr - (fonePtr % 4); /* make sure pointer address is a multiple of 4 */
}
*pSettingsVersion = version();
return getphonesettings();
}
CheckFor56KAndS220(int *has56K, int *s220)
{
char modemResult[32];
flush();
sendstr("ATI3\r");
printf("TellyScript: SENT ATI3");
getline(modemResult, 31, 300);
getline(modemResult, 31, 300);
printf("TellyScript: firmware query returned '%s'", modemResult + 1);
modemResult[21] = 0;
*has56K = 0;
if (strcmp(modemResult + 1, "V1.001_WEBTV-K56_DLP") == 0) { /* Check if our WebTV modem is 56K */
*has56K = 1; /* if so, set the has56K variable accordingly */
}
flush();
sendstr("ATS220=0\r");
printf("TellyScript: SENT ATS220=0");
getline(modemResult, 31, 300);
getline(modemResult, 31, 300);
printf("TellyScript: S220 test returned '%s'", modemResult + 1);
*s220 = 0;
if (strcmp(modemResult + 1, "OK") == 0) {
*s220 = 1;
}
return 0;
}
SetupModemConfig(char *staticConfigBuf, char *dynamicConfigBuf)
{
int foneVersion;
char *phoneSettings = getphonesettings(); // phone settings data
char *fone = GetPhoneSettings(&foneVersion); // get FONE version from ROM
char audibleDialing = phoneSettings[97];
char waitForTone = phoneSettings[101];
char useCallWaitingHack = phoneSettings[103];
char dialSpeed = phoneSettings[104];
char cwSensitivity = fone[105];
char *s220Value, *cwValue = "14";
int has56K, hasS220;
enablemodem();
setflowcontrol(3);
setbaud(57600); // from base.tsf: "meaningless except for Mac simulator"
// if either the modem command or getting the modem details fail (the latter should not happen), then return error
if (SendAndWaitForOK("AT&D2V1E0\r", "OK"))
return 3; /* kTellyConfigurationError */
if (CheckFor56KAndS220(&has56K, &hasS220))
return 3; /* kTellyConfigurationError */
if (has56K) {
printf("TellyScript: found v1.0 K56 firmware, disabling 56K");
strcpy(staticConfigBuf, "AT+MS=11,1"); // copy "AT+MS=11,1" to static config buffer
} else {
strcpy(staticConfigBuf, "AT"); //copy "AT" to static config
}
strcat(staticConfigBuf, "S38=0S30=180S95=36S11=60&D2V1E0L3&Q5&K3\r");
strcpy(dynamicConfigBuf, "ATV0"); // copy "ATV0" to dynamic config buffer
if (audibleDialing && (connectingwithvideoad() != 1)) { // enable audible dialing only if we aren't connecting with
// a video ad playing (WebTV Plus only)
strcat(dynamicConfigBuf, "M1"); // enable audible dialing
} else {
strcat(dynamicConfigBuf, "M0"); // turn audible dialing off (use WebTV dialing music)
}
if (waitForTone) {
strcat(dynamicConfigBuf, "S6=10X4"); // sets S6 register - "Wait Time before Blind Dialing"
} else {
strcat(dynamicConfigBuf, "S6=4X3");
}
if (foneVersion >= 7) {
if (useCallWaitingHack) {
if (cwSensitivity == 1) {
cwValue = "113";
} else if (cwSensitivity == 2) {
cwValue = "116";
} else if (cwSensitivity == 3) {
cwValue = "88";
} else if (cwSensitivity == 4) {
cwValue = "92";
} else {
cwValue = "92";
}
}
} else {
if (cwHack) cwValue = "92";
}
printf("TellyScript: vers=%d/%d, cw-hack=%d, cw-sens=%d, setting S10 to %s",
version(), foneVersion, cwHack, cwSensitivity, cwValue);
strcat(dynamicConfigBuf, "S10=");
strcat(dynamicConfigBuf, cwValue);
if (hasS220) {
if (cwSensitivity == 1) {
s220Value = "32";
} else if (cwSensitivity == 2) {
s220Value = "21";
} else if (cwSensitivity == 3) {
s220Value = "11";
} else {
s220Value = "1";
}
printf("TellyScript: setting S220=%s", s220Value);
strcat(dynamicConfigBuf, "S220=");
strcat(dynamicConfigBuf, s220Value);
} else {
printf("TellyScript: not setting S220");
}
if (dialSpeed == 0) {
strcat(dynamicConfigBuf, "S11=200&P1");
} else if (dialSpeed == 1) {
strcat(dynamicConfigBuf, "S11=110&P1");
} else if (dialSpeed == 2) {
strcat(dynamicConfigBuf, "S11=60&P3");
} else if (dialSpeed == 3) {
strcat(dynamicConfigBuf, "S11=1&P3");
}
strcat(dynamicConfigBuf, "\r");
setwindowsize(3);
return 0;
}
GetPrefix(char *prefix, int isLocal)
{
int foneVersion;
char *phoneSettings = getphonesettings();
char *extendedSettings = GetPhoneSettings(&foneVersion);
char *callWaitingPrefix = &phoneSettings[0];
char *dialOutsidePrefix = &phoneSettings[32];
char disableCallWaiting = phoneSettings[98];
char dialOutsideLine = phoneSettings[99];
char *ldPrefix = &extendedSettings[140];
prefix[0] = 0;
if (disableCallWaiting)
strcat(prefix, callWaitingPrefix);
if (foneVersion >= 8) {
if (ldPrefix[0] && !isLocal) {
printf("TellyScript: Using LD prefix");
strcat(prefix, ldPrefix);
strcat(prefix, ",");
} else {
if (dialOutsideLine) {
strcat(prefix, dialOutsidePrefix);
strcat(prefix, ",");
}
}
} else {
if (dialOutsideLine) {
strcat(prefix, dialOutsidePrefix);
strcat(prefix, ",");
}
}
return 0;
}
SendAndWaitForOK(char *str, char *okstr)
{
int retries = 0;
while (retries++ < 4) {
flush();
sendstr(str);
if (waitfor(okstr, StrLen(okstr), 120)) { // Check if we got the expected response
printf("TellyScript: SENT config string '%s'", str);
break;
} else {
printf("TellyScript: TIMEOUT waiting for OK (str='%s')", str);
WinkDTR();
}
}
if (retries >= 4) {
printf("TellyScript: Couldn't get '%s' from modem", okstr);
setdtr(0);
return 3;
}
return 0;
}
InitModem(char *staticConfig, char *dynamicConfig)
{
setstatus(6); /* kTellyInitializingModem */
ShowPreparingToCall(13);
WinkDTR();
if (SendAndWaitForOK(staticConfig, "OK")) {
setdtr(0);
return 3; /* kTellyConfigurationError */
}
if (SendAndWaitForOK(dynamicConfig, "0")) {
setdtr(0);
return 3; /* kTellyConfigurationError */
}
setforcehook(1);
return (0);
}
ParseResult(int result)
{
int returnCode = 0;
char *comment = "";
if (result == 0) /* OK */
{
comment = " OK";
returnCode = 1; /* okay */
}
else if (result == 3) /* NO CARRIER */
{
comment = "NO CARRIER";
returnCode = 12; /* kTellyNoCarrier */
}
else if (result == 6) /* NO DIALTONE */
{
comment = "NO DIALTONE";
returnCode = 5; /* kTellyNoDialtone */
}
else if (result == 7) /* BUSY */
{
comment = "BUSY";
returnCode = 7; /* kTellyBusy */
}
else if (result == 8) /* NO ANSWER */
{
comment = "NO ANSWER";
returnCode = 6; /* kTellyNoAnswer */
}
else if (result >= 18 && result <= 19) /* CONNECT 57600 and 115200 */
{
comment = "Connected!";
gConnected = 1;
gDTERate = 57600*(result - 17);
}
else if (result == 20) /* CONNECT 230400 */
{
comment = "Connected!";
e = 1;
gDTERate = 230400;
}
else if (result >= 47 && result <= 51) /* CARRIER 2400 - CARRIER 12000 */
{
gDTERate = 2400*(result - 46);
returnCode = 14; /* kTellyVerySlowConnect */
}
else if (result >= 52 && result <= 58) /* CARRIER 14400 - CARRIER 28800 */
{
gDCERate = 2400*(result - 46);
}
else if (result == 66) /* COMPRESSION: CLASS 5 */
{
gCompression = 1;
}
else if (result == 67) /* COMPRESSION: V.42bis */
{
gCompression = 2;
}
else if (result == 69) /* COMPRESSION: NONE */
{
gCompression = 0;
}
else if (result == 76) /* PROTOCOL: NONE */
{
gProtocol = 0;
}
else if (result == 77) /* PROTOCOL: LAPM */
{
gProtocol = 1;
}
else if (result == 78 || result == 60) /* CARRIER 31200 */
{
gDCERate = 31200;
}
else if (result == 79 || result == 65) /* CARRIER 33600 */
{
gDCERate = 33600;
}
else if (result == 80) /* PROTOCOL: ALT */
{
gProtocol = 2;
}
else if (result == 81) /* PROTOCOL: ALT-CELLULAR */
{
gProtocol = 3;
}
else if (result >= 150 && result <= 162) /* CARRIER 32000 - 56000 (K56) */
{
gDCERate = 2000*(result - 134);
}
else
{
printf("TellyScript: ParseResult -- %d unknown", result);
returnCode = 9; /* kTellyUnknown */
}
printf("TellyScript: ParseResult -- %d %s (retcode=%d)", result,
comment, returnCode);
return returnCode;
}
SendAccessNumberToModem(char *accessNumberToDial, int isLocal)
{
int foneVersion;
char *phoneSettings = getphonesettings();
char *fone = GetPhoneSettings(&foneVersion);
char *accessNumberSettings = &phoneSettings[64];
char usePulseDialing = phoneSettings[96];
char brokenPBX = fone[106];
int tollFree, theDollar;
char prefixBuffer[64];
char *prefixStr;
char *afterDollar;
char buffer[32];
if (gUsingOpenISP) {
strcpy(buffer, "ISP-");
StrnCpy(buffer + 4, accessNumberToDial, 31 - 4);
} else {
StrnCpy(buffer, accessNumberToDial, 31);
}
buffer[31] = 0;
setworkingnumber(buffer);
tollFree = IsTollFree(accessNumberToDial);
theDollar = OStrChr(accessNumber, '$'); // Find "$" in phone number
if (theDollar >= 0) {
strcpy(buffer, accessNumber);
afterDollar = buffer + theDollar + 1;
buffer[theDollar] = 0;
}
if (foneVersion >= 8 && brokenPBX &&
(!accessNumber[0] || theDollar >= 0))
{
if (DoStripLeadingDigit(accessNumberToDial)) {
printf("TellyScript: BrokenPBX set, stripping leading digit");
accessNumberToDial++; // increase position in access number
}
}
if (usePulseDialing) {
strcpy(prefixBuffer, "ATDP");
} else {
strcpy(prefixBuffer, "ATDT");
}
prefixStr = prefixBuffer + 4;
GetPrefix(prefixStr, isLocal);
setstatus(7); /* kTellyHandshake */
if (gUsingOpenISP) {
ShowDialingNumber(prefixStr, accessNumberToDial, 26);
} else if (version() >= 8) {
if (accessNumber[0] && theDollar < 0) { // If we didn't find "$" in the phone number stored
// in NVRAM, we have an override number
ShowDialingAccessNumberOverride(prefixStr, accessNumberToDial, 26);
} else if (tollFree) {
ShowDialingWebTV(26);
} else {
ShowDialingNumber(prefixStr, accessNumberToDial, 26);
}
} else {
ShowDialingWebTV(26);
}
if ((accessNumberToDial[0] != 'A') && (accessNumberToDial[0] != 'a')) {
sendstr(prefixBuffer);
printf("TellyScript: SENT prefix '%s'", prefixBuffer);
}
if (theDollar < 0) {
sendstr(accessNumberToDial);
printf("TellyScript: SENT number '%s'", accessNumber);
} else {
sendstr(buffer);
sendstr(accessNumberToDial);
sendstr(afterDollar);
printf("TellyScript: SENT fancy '%s' '%s' '%s'",
buffer, accessNumberToDial, afterDollar);
}
sendstr(";\r");
flush();
return 0;
}
WaitForConnect()
{
char *phoneSettings = getphonesettings();
char audibleDialing = phoneSettings[97];
char modemResult[32];
int i, result, count;
i = 0;
gConnected = 0;
while (!gConnected && i < 6) {
count = getline(modemResult, 31, 4200);
i++;
if (count == 0) { // Modem response timed out
printf("TellyScript: TIMEOUT waiting for modem result");
setdtr(0);
if (i == 1)
return 4; /* kTellyDialingError */
else
return 8; /* kTellyHandshakeFailure */
}
result = ParseResult(atoi(modemResult));
if (result == 1) {
if (i == 1) {
sendstr("ATD\r");
if (!audibleDialing) {
delay(180);
}
ShowWaitingToConnect(39);
result = 0;
} else {
setdtr(0);
printf("TellyScript: got '%s' at odd time", modemResult);
return 8; /* kTellyHandshakeFailure */
}
}
if (result != 0) {
setdtr(0);
if (result == 12 && i > 2) {
return 8; /* kTellyHandshakeFailure */
}
return result;
}
if (i == 2) {
setstatus(2); /* kTellyCarrier */
if (f) {
ShowISPAnswering(52);
} else {
ShowWebTVAnswering(52);
}
}
}
printf("TellyScript: dterate=%d, dcerate=%d, protocol=%d, compression=%d",
gDTERate, gDCERate, gProtocol, gCompression);
setconnectionstats(gDTERate, gDCERate, gProtocol, gCompression);
return 0;
}
DialIAP(char *staticConfig, char *dynamicConfig, char *iapName, char *number,
int isLocal, int *pResult)
{
*pResult = InitModem(staticConfig, dynamicConfig);
if (*pResult != 0)
return 2;
gDTERate = gDCERate = gProtocol = gCompression = 0;
printf("TellyScript: Calling %s/%s", iapName, number);
SendAccessNumberToModem(number, isLocal);
*pResult = WaitForConnect();
if (*pResult)
printf("TellyScript: dialing failure, result=%d", *pResult);
if (*pResult == 4 || *pResult == 5) {
return 2;
} else if (*pResult) {
return 1;
}
return 0;
}
LoginWithPAPCreds(char *userNameBase, char *fixedPassword) // originally named PAPChat by WebTV Networks - initiates PAP login once the box is able to dial into an access point
{
char *serial = getserialnumber();
char username[48];
char password[48];
sprintf(username, userNameBase, serial); // format username string with serial number from SSID, and
// put it in username buffer
/*
* If fixedPassword is 0 or 1, then set the PAP password as the
* FCS16 value (proprietary WebTV CRC-like checksum) of the box's
* serial number.
*
* A JavaScript implementation of the FCS16 algorithm can be found
* here: https://webtv.zone/1800gen.html
*/
if (fixedPassword == 0) {
sprintf(password, "%d", computefcs(serial));
} else if (fixedPassword == 1) {
sprintf(password, "%08d", computefcs(serial));
} else {
strcpy(password, fixedPassword);
}
printf("TellyScript: Using PAP with '%s'/'%s'", username, password);
setusername(username);
setpassword(password);
setpapmode(1);
setstatus(5); /* kNegotiatingPPP */
ShowConnecting(88);
if (!startppp()) {
setdtr(0);
if (getpppresult() == 3) {
printf("TellyScript: PAP authentication failure");
return 10;
}
printf("TellyScript: PPP negotiation failed");
return 11;
}
printf("TellyScript: Link connected");
setstatus(1); /* kTellyConnected */
if (stack() < 0x200) {
ShowStackLow(100);
} else if (f) {
ShowConnectedToOpenISP(100);
} else {
ShowConnectedToWebTV(100);
}
return 0;
}
/*
* Unused in this specific script - determines the time on the WebTV/MSN TV box for
* "poptimized" TellyScripts to choose an access number based on the month,
* day of the week, or hour
*/
WhatTimeIsIt(int* pMinute, int* pHour, int* pMonth, int* pYear, int* pDayOfWeek)
{
int when, tmpyear;
parsesystemtime(7776000); /* from base.tsf: "90 days after Jan 1 1970" */
tmpyear = getyear();
when = getdatetimelocal();
parsesystemtime(when);
if (tmpyear != 1970 || when < 7776000) { // Clock got reset from power loss, or the box is an old Classic (bf0/FCS) and is running in boot ROM mode
printf("TellyScript: time not available %d/%d", tmpyear, when);
*pDayOfWeek = 3; /* Set the time to Wed, Jan 1, 1970 at 7 PM */
*pHour = 19;
*pMinute = 0;
*pMonth = 1;
*pYear = 1970;
return 1;
}
*pDayOfWeek = getdayofweek(); /* 0-6 */
*pHour = gethour(); /* 0-23 */
*pMinute = getminute(); /* 0-60 */
*pMonth = getmonth(); /* 1-12 */
*pYear = getyear();
return 0;
}
DialByIndex(char* staticConfig, char* dynamicConfig, char* sequence) /* Attempts to dial all numbers in a sequence */
{
int status, err, nextNumber, sequenceLen, idx;
if (version() >= 8) {
nextNumber = getconnectretrycount();
} else {
nextNumber = 0;
}
sequenceLen = StrLen(sequence);
printf("TellyScript: next=%d, seqLen=%d", nextNumber, sequenceLen);
err = 13;
for (idx = nextNumber;idx < sequenceLen;idx++) {
status = DialIndexedPOP(staticConfig, dynamicConfig, sequence[idx],
idx, &err);
if (status == 0) {
err = DoPAPLoginBasedOnPOP(popList[idx]);
if (!err || idx == sequenceLen - 1) {
return err;
} else {
dialerror(err);
}
} else if (status == 2 || idx == sequenceLen - 1) {
return err;
} else {
dialerror(err);
}
}
return err;
}
main()
{
char *phoneSettings = getphonesettings();
char *accessNumber = &phoneSettings[64];
char staticConfig[80];
char dynamicConfig[80];
int start = ticks();
int err, result = 0;
err = InitTellyScript();
if (err)
return err;
err = SetupModemConfig(staticConfig, dynamicConfig);
if (err)
return err;
setprogressmode(1); /* from base.tsf: "take control of the status bar (version >= 8)" */
setfullpopnumber(""); // clear POP number and variables for OpenISP and gNVRAMMayBeInvalid
gUsingOpenISP = 0;
gNVRAMMayBeInvalid = 0;
if (accessNumber[0] && OStrChr(accessNumber, '$') < 0) {
result = AccessDial(staticConfig, dynamicConfig, accessNumber);
if (result == 10)
result = 15; /* BadPasswordNR */
} else {
result = PatternDial(staticConfig, dynamicConfig);
if (result == 10)
result = 15; /* BadPasswordNR */
}
if (!result) {
printf("TellyScript: success, in %d seconds",
(ticks() - start) / 60);
return 2; /* kTellyLinkConnected */
} else {
setconnectretrycount(0); /* from base.tsf: "temporary fix for 1.3.x" */
printf("TellyScript: failure #%d, in %d seconds", result,
(ticks() - start) / 60);
setdtr(0);
return result;
}
}
IsTollFree(char *numberToDial)
{
if ((numberToDial[1] == '8' && numberToDial[2] == '0' && numberToDial[3] == '0') ||
(numberToDial[1] == '8' && numberToDial[2] == '8' && numberToDial[3] == '8'))
{
return 1;
}
return 0;
}
DoStripLeadingDigit(char *numberToDial)
{
if (*numberToDial == '1')
return 1;
else
return 0;
}
ShowPreparingToCall(int percent)
{
SetDialingProgress("Preparing to call", percent);
}
ShowDialingNumber(char *wa, char *accessNumber, int percent)
{
char message[128];
sprintf(message, "Dialing %s%s", wa, accessNumber);
SetDialingProgress(message, percent);
}
ShowDialingAccessNumberOverride(char *wa, char *accessNumber, int percent)
{
char message[128];
sprintf(message, "Dialing A/N %s%s", wa, accessNumber);
SetDialingProgress(message, percent);
}
ShowDialingWebTV(int percent)
{
SetDialingProgress("Dialing WebTV...", percent);
}
ShowWaitingToConnect(int percent)
{
SetDialingProgress("Waiting to connect", percent);
}
ShowISPAnswering(int percent)
{
SetDialingProgress("ISP answering", percent);
}
ShowWebTVAnswering(int percent)
{
SetDialingProgress("WebTV answering", percent);
}
ShowConnecting(int percent)
{
SetDialingProgress("Connecting", percent);
}
ShowConnectedToOpenISP(int percent)
{
SetDialingProgress("Connected to your ISP", percent);
}
ShowConnectedToWebTV(int percent)
{
SetDialingProgress("Connected to WebTV", percent);
}
ShowStackLow(int percent)
{
SetDialingProgress("Warning: stack low", percent);
}
PAPLogin_artemis() // WebTV ISP
{
return LoginWithPAPCreds("wtv_%s", 0);
}
PAPLogin_cnc()
{
return LoginWithPAPCreds("%s!webtv", 0);
}
PAPLogin_cnc2()
{
return LoginWithPAPCreds("%s@usage.webtv.net", 0);
}
PAPLogin_unk1()
{
return LoginWithPAPCreds("UTV/%s", 0);
}
PAPLogin_uunet()
{
return LoginWithPAPCreds("WTV/%s", 0);
}
InitTellyScript()
{
printf("TellyScript: base.tsf version 49 (ANI=123-456-7890)");
setnameservice(0xcf4f238d, 0xcf4f238e);
setani("123-456-XXXX"); // Phone number that appears on "Have You Moved?" dialog box
setlocalpopcount(4);
gNVRAMMayBeInvalid = 0;
return 0;
}
DoPAPLoginBasedOnPOP(int popIdx)
{
if (popIdx == '0') {
return PAPLogin_artemis();
} else if (popIdx == '1') {
return PAPLogin_cnc();
} else if (popIdx == '2') {
return PAPLogin_cnc();
} else if (popIdx == '3') {
return PAPLogin_uunet();
} else if (popIdx == '4') {
return PAPLogin_uunet();
}
return 16;
}
DialIndexedPOP(char *staticConfig, char *dynamicConfig, int idx, int yb,
int *result)
{
char *accessNumber, *provider, *pop = "";
int isLocal;
if (idx == '0') {
pop = "800-610-8918";
accessNumber = "18006108918";
provider = "artemis";
isLocal = 0;
} else if (idx == '1') {
pop = "256-519-4030";
accessNumber = "12565194030";
provider = "cnc";
isLocal = 1;
} else if (idx == '2') {
pop = "256-519-4030";
accessNumber = "5194030";
provider = "cnc";
isLocal = 1;
} else if (idx == '3') {
pop = "205-533-1663";
accessNumber = "12055331663";
provider = "uunetdan";
isLocal = 1;
} else if (idx == '4') {
pop = "205-533-1663";
accessNumber = "2055331663";
provider = "uunetdan";
isLocal = 1;
} else {
printf("BUG!");
*result = 16;
return 2;
}
setfullpopnumber(pop);
return DialIAP(staticConfig, dynamicConfig, provider, accessNumber, isLocal, result);
}
PatternDial(char *staticConfig, char *dynamicConfig)
{
return DialByIndex(staticConfig, dynamicConfig, "24130");
}
AccessDial(char *staticConfig, char *dynamicConfig, char *accessNumber)
{
int status, err, nextNumber;
if (version() >= 8) {
nextNumber = getconnectretrycount();
} else {
nextNumber = 0;
}
printf("TellyScript: next=%d", nextNumber);
if (nextNumber) {
return 13;
}
status = DialIAP(staticConfig, dynamicConfig,
"-access-", accessNumber, 1, &err);
if (status) {
setdtr(0);
return resultCode;
}
err = PAPLogin_cnc();
return err;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment