Monday, April 6, 2015

FIX: Fix Plex Media Server Remote Access / Unable to Connect to Plex from The Internet (code=-52)

Symptoms
You've opened the ports on your firewall and verified that they are open via an open port check tool on the Internet.
You've tried Why am I locked out of Server after password reset or device token removal. You've successfully pulled out many locks of hair (optional).
You've even turned on UPnP on your router, just to test (you can turn it off, just make sure the port is opened and forwarded correctly).
Error 52 / code=-52
Your log has this line:
WARN - MyPlex: Invalid response when mapping state (code=-52)
What's happening
Some part of the Remote Access registration process fails if the host operating system is configured to use Jumbo Frames. If you don't know what that means, that's OK. I'm running an OpenSuSE Linux box as my Plex server and I am not a Linux expert, so I can't even really tell you where to go (if you know, leave a comment, please!).
For OpenSUSE, do the following:
$ sudo yast
... Your password ...
In yast, go to Network Devices and select Network Settings.
Select each network adapter and choose Edit.
Go to the General tab and change the MTU to a value that will prevent Jumbo Frames (1400 is a safe test value for most people, but you can google your optimal based on the kind of broadband you subscribe to).
Exit and try it all again (I restarted the plex server as well, just for good measure).

Monday, March 30, 2015

Nermerle, Nitra, Parsing and Functional Programming

Functional Programming

I started looking into Functional Programming about ten years ago and became pretty comfortable with F#. I initially explored it as part of a project I had embarked upon to parse a DSL and provide a suitable development environment that a non-developer could use to customize my application. It was a lofty goal and ultimately was scrapped in favor of a much stripped down model that was driven via web forms and a small subset of the features, but the DSL was still available for more complex needs.

Parsing HLSL

Recently that need arose again. I've been messing around with WPF Shader Effects and 2D sprites. No, I'm not developing a game (sorry, no real interest here). The biggest frustration for me has been the lack of debugging information available. My usual process for exploring new languages is a combination of reading/research and poking/reverse engineering. I was the kid that took apart every piece of broken/outdated electronics growing up. After picking up "The Basics", I usually dive right in and write some (terrible) code to see what it does. I'll also read/step through open source code that I think I conceptually understand to validate my understanding.

Hlsl makes my learning process more difficult. I can't step through the code; I can't watch. The way it encodes colors into float4 values is sufficiently different from what you'd expect that predicting what the value would be requires you to know about things like Premultiplied Alpha, mapping textures to float values between 0 and 1. Your college calculus class will come in handy even if you did poorly as most things related to programming/math require you to have a good understanding of how it works even if you don't remember the details. Wolfram|Alpha will will help you if you've forgotten the specifics.

Built-in IDE tools provide barely any information when the HLSL files are rendered by WPF. I'm not sure how valuable they are outside of that, but they're useless here. The larger tools available from NVidia/Intel are overkill and mostly don't cover the areas I was hoping (the NVidia product simply didn't support most of its features on my particular GPU ... Notebooks).

Building a narrow-purpose IDE

I started out exploring WPF ShaderEffects using the wonderful Shazzam. Unfortunately, at the time of this writing, downloading the tool from his site isn't possible but a slightly outdated version (in code only) can be acquired from CodePlex. I tweaked it a bit for my purposes and created a shader effect that I mostly liked. Getting to the fine details, though, was difficult and I knew I'd need more insight into what was going on.

Enter Nemerle, F# and Nitra

The first thing I wanted was better parsing of the code before compile. I went digging around and found a syntax highlighting definition for HLSL. The language has some unique elements, such as Vectors whos parts are accessed via array notation, or .xyzw .agbr notation. It's quite elegant, but my eyes weren't naturally parsing it coming from languages that didn't do that.

The rabbit hole began there. The editor used by Shazzam was a way old version of that used by SharpDevelop. It's since been updated and the core text editor can be grabbed independently from NuGet as AvalonEdit. It works quite differently from the version offered by Shazzam, and syntax highlighting is much more powerful. So I created a Syntax Highlighting Definition for AvalonEdit that would color the .argb items as a variant of gray, red, green and blue and used shades of gray with underlining for the wxyz (I'll get the definition out on GitHub when I have a chance and link to it here).

The Shazzam tool was also missing Intellisense and some of the code signals that Visual Studio provides, so I went looking for a solution there knowing that my old friend F# was probably going to find a way back into my life for this one.

Surprisingly, it was Nemerle and the [Nitra Project from JetBrains]|(http://blog.jetbrains.com/blog/2013/11/12/an-introduction-to-nitra/) that got my attention this time. Tom Jones' Getting Started with JetBrains Nitra specifically covered parsing HLSL! Thanks for that!

It lacked the ability to understand shader2D and had no preprocessor support, but after adding shader2D, I now had a library that easily integrated with AvalonEdit to provide syntax highlighting failures and guidance for repair... All from a concise syntax file.

I wanted something a little more. Inspired a while ago by Bret Victor's Ted Talk, I decided to see if I could create an IDE that would give useful feedback about how the program works while it is being developed. HLSL is a limited purpose language, and WPF ShaderEffects limitations limit it even further. It's the perfect target for an IDE that gives intelligent feedback about the program being written while it is being written. By providing sample inputs and the ability to provide custom inputs for the function, a person can see what the outcome of the code would be in various scenarios,... as close to live as possible.

At this point, I'm building a new HLSL parser specifically targetting the limitations imposed by WPF to ensure that code syntax and rules are followed carefully.

I'm then going to start evaluating ...

Enter the God Awful Visitor Pattern

I'm an OOP guy most of the time. The pattern fits well much of the time and most .Net programmers are comfortable with it. However, The Visitor Pattern hurts my brain.

C# lacks Multiple Dispatch without the DLR. I'm not interested in passing type safety all the way to runtime. The Visitor Pattern is the way around that problem. The pattern is relatively straight forward, but figuring out its intent by looking at the code is painful. F# and Nemerle have pattern matching capabilities and allow multiple dispatch. The resulting code is readable with a small reference to the syntax (Nemerle is easier to read coming from C# than F#, IMHO) and the amount of resulting code is substantially less.

My Plan for Next Time

Unfortunately, this is not my day job. It's Saturday/Sunday Early Morning/Late Evening work. I have no code samples at the moment because I just moved my F# code to Nemerle (and it's so much easier to understand). I hope to spend some time with the parser next weekend when I will have a little more time to poke at it. If I get it to the point I want it, I'll write it up and thow it out on GitHub.

Until then ... Don't panic!

Nemerle documentation can be found here.

Nitra syntax, not terribly well documented, but somewhat easy to follow after going through the Nemerle documentation.

Tuesday, March 24, 2015

HOWTO: Add Code Syntax Highlighting to your Blogger / BlogSpot Blog

Solving my own problems
Last year I decided to poke about in my blog again and managed to utterly destroy the template along with all of my past customizations. I've decided to take the time to figure this out and then document it so that I can do it again when I decide to "code in production" again. So in the typical, slimmed down style, here's how it's done.
  1. Get to your blog's dashboard (log in, select blog from blogger dashboard).
  2. Select Template on the left hand navigation and Edit HTML on the screen that loads
  3. Locate the </head> tag (side note for testing later: better to not put this in head because it will prevent page from displaying until loaded).
  4. Paste the (hopefully now highlighted) code below. We're using cdnjs as the host for the .js scripts. I've read other instructions that suggest hot-linking directly to the author's site. I checked the install instructions on the site and he specifically asks you to copy the files locally.
Template Code
Here's the code I added to <head>:
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushPlain.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushCSharp.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushBash.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushJScript.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushXml.js"></script>
<script type="text/css" src=""></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css" rel="stylesheet" type="text/css" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeMidnight.min.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
 SyntaxHighlighter.config.bloggerMode = true;
 SyntaxHighlighter.all();
</script>
And the Html
I've included the exact HTML used to render the above. Note that the "<"'s are all replaced with &lt;. That's a limitation I've decided to accept rather than using the alternative <script> block style.
<pre class="brush:js">
&lt;script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js">&lt;/script>
&lt;script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushCSharp.min.js">&lt;/script>
&lt;script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushBash.min.js">&lt;/script>
&lt;script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushJScript.js">&lt;/script>
&lt;script type="text/css" src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushXml.js">&lt;/script>
&lt;link href="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shCore.min.css" rel="stylesheet" type="text/css" />
&lt;link href="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/styles/shThemeMidnight.min.css" rel="stylesheet" type="text/css" />
&lt;script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushXml.js"></script>
&lt;script type="text/javascript">
 SyntaxHighlighter.config.bloggerMode = true;
 SyntaxHighlighter.all();
&lt;/script>
</pre class="brush:js">
Customizing for your purposes
SyntaxHighlighter can be customized. At this point, there's many available syntaxes to choose from. Find the brush you want and visit the cdn.js page for SyntaxHighlighter to get the link.
There's also plenty of themes. Find what you want, visit the cdn.js page for a link and add it to the scripts above.

Saturday, February 14, 2015

Weekend Adventures in Coding - Visual Studo Customization - Order of Adornment Layers

When Visual Studio 2010 came out, I started looking into customizing the environment a little beyond what was able to be done with existing extensions. I was looking for the ability to place a background image underneath code and fix some issues with font rendering (particularly around the input font). I had succeeded in getting the background properties set through an extension I wrote (similar to ClaudiaIDE, but with a simple property set instead of adding an adornment layer -- it served my purposes but with some limitations). This morning, I tweaked my extension and brought it up to support 2013 (wow, was that easier than I expected!).

Font rendering was helped by re-running the OSes Clear Type configuration and installing Text Sharp. If this sort of thing is important to you, you also want this free gem: MacType. It causes Windows to render fonts in a way that is more similar to a Mac which I find improves readability substantially. Unfortunately, it doesn't work perfectly everywhere, but some of Visual Studio is affected.

I've decided today to see if I can apply the last bit, a white shadow to text. This is a common effect throughout MacOS/iOS and I find it improves readability (particularly for high-contrast backgrounds).

Here's what I'm looking to apply (apologies for formatting, I'll get the code formatter working again, soon).
item.Effect = new DropShadowEffect
           {
            Opacity = 0.34,
            ShadowDepth = 9,
            Direction = 542,
            BlurRadius = 9,
            Color=Colors.White
           };
Finding an efficient way to do this (preferably without having to hack about with Reflection) has been frustrating, but I've managed to apply all kinds of effects elsewhere while I was attempting to fill in the gaps of the documentation with some reverse engineering.
Default order of Adornment Layers
While poking about, I thought it might be helpful to know the order of the default adornment layers. I just started (re-)evaluating OzCode and it was picked up by the "Exp" (temporary debug instance), so some of these belong to that. I'm also on CU4 so any that aren't documented may belong to that (search PredefinedAdornmentLayers or hit F1 for the documented ones).

CodeBackgroundTextAdornment
vsMergeHighLightSpaceAdornment
Outlining
DiffernceChanges
Difference Space
BraceCompletion
DeltaFullLineAdornment
DeltaNegativeSpaceAdornment
HtmlProvisionalTextHighlight
CurrentLineHighlighter
VsTextMarker
TextMarker
HighlightCommentAdornment
SelectionAndProvisionalHighlight
Inter Line Adornment
Squiggle
LineSeparator
CollaborationMethodEndorsement
ScriptDebuggerSectionDivider
Text
PinnedLayer
vsMergeHighlightSpaceAdornmentAboveText
SmartTag
DragDropAdornmentLayer
Intra Text Adornment
VisibleWhiteSpace
Caret
SimplifyVisualController
PinnableTips
InitialDifferenceWaitingAdornmetLayers
HtmlChrome
I have no idea what I'll be doing with these, but that's the fun of reverse engineering. If you have to do such a task, OzCode is very helpful. It allows searching the contents of objects through several layers and can surface interesting bits to play with. This is, of course, experimental and likely will break between updates, but they've made extending Visual Studio so easy, it's not that bad to tweak between updates/versions. More to come if I figure this out!

Saturday, February 7, 2015

Another chapter after 17 years

On to new things!
After 17 years, I have decided to resign my position at Level (3). 17 years. That's a lifetime in IT. I started at a small telecom located in Southfield, MI and ended up at an international telecom with a headquarters in Broomfield.
What a ride
I started as a desktop tech, within a half-year I was doing servers. Ultimately Allnet was purchased by Frontier, Frontier by Global Crossing and then the bottom fell out. For the remaining years until about last year, I worked for a company that was effectively a start-up in a very competitive sector. Layoffs every year were normal while Global Crossing struggled (and ultimately succeeded) with survival. Level 3 purchased Global Crossing in 2011. For 15 of those 17 years, I rode the wave down and for the last two I've been riding it back up. It was strange working for a company that was not operating in survival mode.
It was 17 years for me, but nearly every year I was given a new position, more responsibility and new and interesting projects. Mix in the fact that I was working amongst, what I considered to be, some of the best people in our industry.
Onto Development
I'd always been a programmer. I'm not sure why I took the ops route originally, but within two years I was writing code that was changing the way our employees worked and I knew right away that this is what I was made to do. I love programming...love it. Over the years I was given the freedom to code, experiment and learn. I quickly jumped on the C# bandwagon, missing the days of hacking about in C and Pascal/Delphi and fell in love. And I learned...
So why now?
After 17 years, I've discovered that it's time for me to move on. During my time at Level 3, I had the privilege of working on some special projects involving Lync and Office Communications Server. This was my first exposure to an API that I couldn't simply Bing (there's one for you, MS) a million answers from people who had just learned the API. The APIs I was working with were pre-release, but after release the situation wasn't much better. For some reason, I enjoyed this immensely!
What now?
I had sent my resume out to Modality, a Microsoft Partner and a company with a very successful business in the Lync space, earlier last year. This wasn't unusual for me. If someone mentioned a job that sounded interesting to me, I usually prepped my resume, took and interview and turned down the job. It's happened so many times over the years that I almost expected to make the same decision when Modality had a position available to me. After talking to the guys over there, much to my own surprise, my mind was made up.
I'll be a US based, "work from home" (I prefer remote) employee working for a company that sells services and software for an application that, since 2008, has been the reason I could work effectively as a remote employee for Global Crossing and ultimately Level 3. Being a part of a company that was an early adopter--eliminating all phones on PCs and replacing them with USB headsets and speakerphones was far less of an adjustment than anyone could imagine---was great for me. The quality and effectiveness of audio conferences suddenly made it possible to have a workforce that was distributed far and wide without losing much other than water-cooler conversation.
Finally
Farewell, my Level 3 coworkers and friends! You are among the best and many thanks for the help, support and just-plain-fun you've given me over the last 17 years.

Thursday, November 20, 2014

Watching a Delta Jet Land Directly Overhead from the Beach in St. Martin (Sunset Beach / Airport Beach)

I just returned from my vacation and am not yet ready to post the "big review" quite yet. But I had to share this. Earlier this week I wrote "Today, I had a plane pass over me so close, I could lick it."

Here's the video.  It doesn't do the experience justice.  At the end, you'll hear the roaring wind that's all around us. The phone's microphone is totally overwhelmed.  It was just neat!

If you're interested in doing this yourself, find any Eastern Caribbean cruise that visits St. Maarten/St. Martin island. Take a cab from nearly anywhere to Airport/Sunset Beach, the rates are set by the government, for us it was $20.00 USD for my wife and I to get there.  Watch a few puddle jumpers land to position yourself, and enjoy.

I'll post the other videos I grabbed from less ideal locations, but here's the best one:


Wednesday, November 5, 2014

FIX: T-Mobile Wireless (WiFi, not 3G) CellSpot / ASUS TM-AC1900 Port Forwarding Not Working

Problem
You try to forward ports on your new $25 deposit ASUS Wifi awesome-router and it doesn't work. Neither does UPNP. Or maybe it works but not for very long.
What's happening
Those clever folks at ASUS added a NAT acceleration capability. Unfortunately, as best I can tell, it basically does nothing much better than crash regularly. This is why you may have noticed that forwarding works occasionally after reboot. I, personally, found this to be very rare. I've also found that the NAT acceleration isn't noticed when it's disabled. I don't have Google internet, but I'm pulling 80/20 and the router is doing fine.
Fix
Go to LAN -> Switch Settings. It will probably hang. Worry not, your router probably just crashed. You likely lost internet. Give it a full minute and refresh.
Go to LAN -> Switch Settings. Set any setting that has the word Acceleration (or NAT) in it to Disabled. Your router will reboot and your ports will be forwarded.

Update: Around December, for no apparent reason, my NAT rules all stopped working again. Nothing had changed on the router (well, as far as I know ... we rarely need that functionality). See the comments for what I did to repair, but I'll summarize: Factory Reset and some other steps.
I couldn't find better information to help with this, so I went nuclear and blew away the entire configuration. It worked, but ... yuck!

My AT&T U-Verse Nightmare - Going on Two and a Half Years with Broken U-Verse High-Speed Internet

Update 2: This, at least, sounds like a similar problem.

Update 1: I can't believe I'm saying this but Comcast to the rescue? I had a wonderful customer experience with a CSR, purchased Comcast service to replace my U-Verse TV at home until Comcast gets a digital line to my house. I'm told this will happen before the house gets its most use next summer! Also filled in some details...

The following is an account of my lousy experience as an unhappy customer of AT&T U-Verse (Specifically their High-Speed Internet DSL variant). It is accurate to the best of my recollection. This isn't one of those horror stories where the company bankrupted the victim or anything like that. It's just one of frustration and banging of heads into walls... I hope it will be entertaining and informative to you, dear reader, but I make no guarantees. This post is to get out my frustrations and hopefully plan a new solution to this problem. These are my personal opinions, and though my wife would probably agree with me, many others that associate with me may not. Don't blame them. I'll update with new information (or any adjustments as this was "from memory" as they come along).
The Lake House
No, this is not the movie. My family purchased a cabin up north. If this seems strange to you, you don't live in Michigan. Seriously, nearly everyone has one. These communities are, to say the least, underserved. For the most part they're a mix of rural and vacation property. My dad swore he'd never get a place up north. He did. We're really glad they did!
Of course, being the most technically savvy in the family, the first thing I reached for was Internet access and I was pleased to find that AT&T offered 12/1 Internet service! Woot! I'm on-call and knowing that I could actually WORK from up there if I had to was a pretty nice thing.
Never Ending Quest for TV
The first thing we started looking into was TV. No dice. Comcast is the cable provider and they're analog only. Up until very recently, they offered so few channels for the price ($45) it was an extremely bad value. This was coupled with the problem that they offered no internet.
A side note to cable/ISPs: When I call up and ask if you have service, ask for my address and verify, especially in small communities. Comcast's regional office was certain we could get digital service with internet. Not until digging down to the address was it realized that this was not possible.

Next was DirecTV/Dish. The property is very low lying, but in this area that's normally not a problem. The location of the property, however, makes it impossible to hit either satellite. There are some options but all involve installations that Dish/DirecTV installers are "forbidden from doing". Understandable, you don't need your employees dying to install service to your customers.
AT&T was out because the "U-Verse" branded service that they offer is really just slightly improved DSL from the early 2000s.
Hacking together a solution: VerseFinity
I've been a cord cutter for a long time, but my mom really likes to watch the news before going to sleep. Sleep habits are tough to break! My normal route of Netflix, Plex and Hulu would not suffice. My dad had purchased a Slingbox and since I have Comcast Business Internet at home, the bandwidth was sufficient between AT&T and my connection at home to share Plex and Sling with no issues. Couple an iPad and an Apple TV or Roku (we have both) and you have a slightly clunky, but totally usable solution. And two rather non-price-optimized bills.
The first sign of stupidity
At my home I have U-Verse TV. I have SD service and one box. It's getting service from AT&Ts IP network using a low-end DSL modem (SD service doesn't net you the nice one). It's plugged into a Sling Box that pushes the TV signal out Comcast to my AT&T U-Verse Internet up north. Interestingly enough, it's coming in on the very same model low-end DSL modem that it's being sent to in my home! So basically, AT&T does sell IPTV service up north, you just have to buy a house somewhere else, Business Internet from Comcast and U-Verse TV.
Trying to Right my DSL Past
I have had DSL service before, but this was around 2000-2001. At that point, almost all broadband installations were difficult, and almost all had problems after the fact. Eventually, however, they'd get fixed. My first trip around the DSL block in 2000 netted me an almost identical problem to what I'm experiencing. I ended up running a new wire in the house, fresh for the DSL connection and that resolved everything.
Knowing this, and knowing that I have a history of running cable (and all of the basic equipment to test such cables), I eliminated all of the existing home wiring. We were not planning on having home phone service up there--we're well served by all carriers on the property--so it was gone. It was replaced with one straight run from the source about 15 ft. CAT-6 cable with the pairs wired properly. My own equipment can tell me a lot.
The intermittent mess - Beginning in 2012
The service never worked reliably. From the day it was installed it dropped off intermittently (which got worse progressively). It'd do this for a minute, look like it was going to connect again, disconnect, reconnect and be stable for a few minutes to a few hours. All. Day. And. Night. I called tech support and they sent someone out quickly. He saw no problems. Great. None-the-less, he replaced the box on the outside of the house and cleaned up all of the connection points. He checked my wire. Clean.
Throughout the summer we disconnect a bit. We had TWO techs come out. One replaced the modem, one checked everything and did something ... I'm still not clear. Still magically the internet worked and didn't work... mostly not working. Toward the end of the summer we had another tech out because the connection was really flaky. He replaced the modem. It seemed fixed, briefly, but it returned. Again.
At the end of the year, I started noticing something I noticed with DSL service at a previous residence. When the weather would turn cold or rapidly change in temp, the modem would disconnect/reconnect continuously. Warm working days would give into freezing cold, barely 30-seconds of Internet between minutes of disconnection. There's little to do up north in November while waiting for a tech for 8 hours on a Saturday... at a $25 gas bill each time.
After 3 tech visits and 6 months of barely functional service, I'm getting frustrated.
I make one last arrangement in late November 2012. A tech visited and actually saw the problem on the line while visiting (it was easy to see, it was happening every ten minutes).
"Everything looks clean for a few minutes for a while then *BAM* thousands of errors."
He said it could be something related to the connection points on the wire all the way to the CO. As the wires expand/contract, they disconnect/reconnect. Look, I work in telecom, but I have nothing to do with the actual telecom stuff. I know a lot about communications equipment, networking, wiring ... It didn't sound exactly right, but it was better than the nothing explanations I'd been getting so far. The tech suggested that switching out the modem and switching the port at the CO might help.
Side note: This is where that explanation falls off. If the issue exists at a point where a wire connects with another wire "in the elements", I would expect that replacing/changing two things that reside in (I'm assuming) a temperature controlled environment isn't going to help. Nuts.
It might have worked?
The internet service seemed to come back for the remaining time that we were there. I suspected that it would still fail so I put a RaspberryPi up there to serve as a way to send small bits of data back and forth and record success/fail in Nagios.
When the issues with the home were handled, we returned to internet service that was just down. This was the first point at which I started yelling on Twitter/Facebook. I didn't do so to get any attention, I was just angry!
Social Media to the Rescue? Maybe?
I got attention with my Facebook post. Suddenly my phone is ringing and helpful, state-side, folks are assuring me that everything is going to be fixed. A person is coming up there tomorrow. You don't have to be there. They did. They discovered the need to send someone out.
I was assured during this time that everything was going to be handled. I'd be credited. I'd be well taken care of. We're very sorry, sir. (sir, me?).
I was told that they'd do a something-or-other "Home Run", which was described as "we'll just give you new wiring so that at least we know it's our stuff".
I was told they'd replace the modem. Again.
Upon calling to set up the appointment, I made the mistake of contacting regular customer service.
The second sign of stupidity
Evidently yelling on Facebook/Twitter gets you put into some sort of "Second-Class" tech support line. I say second class, because I am still not impressed, but compared to the way you're treated when you call the regular support line? Good Grief.
The difference between Second and Third Class Support
In second class, I get all of those things I was told I would get. I didn't really want any of them. I wanted working Internet. I knew my pristine wire and all of its connections were clean. The modem had been replaced. Twice. Good grief, AT&T, what a waste of money! None-the-less, I was getting it because it might just magically fix the problem. And I was getting it with apologies for the frustrating service experience I'd had thus far.
Not so when I called Third Class support. My very friendly but exceedingly unhelpful representative told me that modems aren't free nor is home wiring. The modem would be at least $200. I explained I didn't want it and that the "other guys" had set that up. I'm assuming AT&T uses some sort of ticketing system that falls very short of providing call center employees with useful information. This person should have known I was working with someone on an ongoing issue. I told the rep I'd try my hand at the phone number given to me in the e-mail. I did. My rep (names omitted even though they're probably internal-use aliases) assured me everything would be taken care of.
2014
The tech came out, replaced the modem and inspected the line. He told me the wire was better than what he'd install and wasn't worth doing. It tests well. Again, he left me with the impression that he thought he fixed the problem but couldn't articulate what the problem was. And, look, the modem is connected again. And it's a different kind of modem! Interestingly enough, this one displays a giant statistics page.
I was bumped from one social media rep to another and basically lost. The internet service continues to go up and down and it's basically unusable during the winter. But this is what happens when you have one provider for a huge geographical area with extremely old equipment trying to somehow make it do magic.
I've surveyed my neighbors. Most of them have U-Verse. Most of them assume it's normal for it to disconnect. The ones that know it isn't gave up trying to get it fixed. It comes and it goes.
So when you hear that Broadband penetration is "x" in the United States, think of all of those areas that are about 30 miles away from a major city. In my rural cabin community, the survey indicates 12/1 service provided by AT&T. My guess is that needs a giant asterisk followed by "where it works at all and we don't just string you along until you give up complaining ..."
Options?
There are very few. AT&T is the provider of choice and if you pick someone else you're on their equipment anyway. There's Fixed Wireless provided by a few rural providers but the service is "five times the price and a tenth the speed". In addition, being on low lying property like that, the chances of getting a line of sight signal are nil.
I see the orange Comcast Digital cable and I have talked to folks in town that have Comcast Digital service and internet.
The last sign of stupidity
I'm actually hoping that Comcast moves into the area so that I get better customer service. Good God, what is wrong with the world?


That might not have been fair. I have been a Comcast Business Internet customer for 5 years and I couldn't be happier with their customer service. I have not, however, had great experiences with their residential service folks.

Wednesday, June 18, 2014

FIX: ORA-00911: invalid character in c# but seemingly nowhere else

I am not normally a developer who targets Oracle, but something recently required me to go down this rabbit hole. I'm the first to admit that I hate Oracle primarily because I lack experience with their dialect of Sql and ... well, Java (Ask toolbars and security issues, grrr). But I digress.
The world's most useless error message
I write this at least partially as a joke because the specific solution I'm going to propose was a fix for my specific problem but because of the ambiguity of this error message, your problem could be something entirely different. Basically, what the Oracle database query parser is trying to tell us is that out of the hundreds of characters in your command text, at least one of them (maybe more) is not a character that it should be. It is, instead, an invalid one. Most likely, you've smashed two keys at the same time and put an errant underscore after a parenthesis. Maybe it's an obvious problem. Or maybe, like me, your unfamiliarity with Sql*Plus combined with this obtuse error led you down the wrong path a few times.
Bad semicolon
There's something about the Oracle provider in C# that causes it to crap all over your statement if the last character in the command text is a semicolon. Note that I've only tested this in the ODP.NET (DataAccess.dll not ManagedDataAccess.dll) 12.x client. In my case, I assumed it was that strange looking colon in front of the variable names. Nope, colon: Good. Semi-colon: Not so much.

Wednesday, December 25, 2013

Part VI - The Ultimate Linux Home Router - SquidGuard - Internet Filtering

Introduction

It's worth warning that perfect internet filtering is impossible. It's for this reason that parents who have older children often don't bother with it since it tends to filter out benign things. That said, I have young children with tablets that Santa bought them for Christmas. I've locked the tablets down rather thoroughly on their own--prohibiting the use of the browser without a password and using a simple tool to restrict YouTube access. I know, however, that there will be times that they'll need the browser and when they do, they'll be using a browser with most controversial subjects filtered out. Don't get me wrong, I'm not interested in Nerf(tm)ing up the internet and preventing them from seeing some of the realities of life. But when they need unrestricted access, I will be there supervising directly. When I can't, most of the internet will be blocked.

Run an update

Since it's been a few days since this was posted, it's worth making sure we're running the latest versions of everything. Run the following and follow any onscreen instructions.
$ sudo zypper up

Installing SquidGuad

$ sudo zypper in squidguard

Restricting Tablets - DHCP Reserved Addresses

One option (and certainly not the most bulletproof) is to set the tablets up with static IP addresses. This is really simple to get around if your children have any basic understanding of IP networking (or know how to wield google in their favor). In a later post, I'll be adding authentication to the proxy server, but until then, I wanted to at least force DHCP to assign the same address. The settings panel on my tablets is password protected, so one of the kids changing the settings is not a huge concern of mine. In addition, assigning the IP via DHCP ensures that I won't need to make other configuration changes when the tablet moves to different networks.
Reserved addresses are assigned when the DHCP server sees a client with a specific MAC address. Since it's easier to retrieve the current IP address on my tablets, I've written down the two addresses: 192.168.0.121 and 192.168.0.127, and we'll look up the host details on the server.
The following command will display all of the current leases
$ cat /var/lib/dhcp/db/dhcpd.leases | egrep "(^lease)|(hardware)"
This will display all of your current leases and their MAC addresses. Find the one that matches what was assigned to the tablets and copy the hardware address.
$ sudo nano /etc/dhcpd.conf
Find the subnet that corresponds to your network. It'll look something like this:
subnet 192.168.0.0 netmask 255.255.255.0 {
  range 192.168.0.100 192.168.0.200;
  default-lease-time 14400;
  max-lease-time 172800;
}
Modify it:
subnet 192.168.0.0 netmask 255.255.255.0 {
  range 192.168.0.100 192.168.0.200;
  default-lease-time 14400;
  max-lease-time 172800;
  host girlstablet {
    fixed-address 192.168.0.30;
    hardware ethernet xx:xx:xx:xx:xx:xx;
  }
}
I've added a host 'girlstablet', which has the MAC address "xx:xx:xx:xx:xx:xx" assigned it the address 192.168.0.30. I'll be putting all of the restricted devices on the 192.168.0 subnet in the range 192.168.0.30-39. Do the same with any other addresses, assigning them an IP address outside of the normal lease range.
Save and Exit, then run:
$ sudo rcdhcpd restart

Installing Blacklists

I'm going ot use Shalla's Blacklists for this example, but there are several others available. Shalla's is for private, non-commercial use only. If you're using it for a business, consult their web site to ensure you are compliant. Creating a script to download the filter list:
$ sudo nano /usr/sbin/update_squidguard_blacklist
Paste in the following and Save/Exit.
#!/bin/sh

cd /var/lib/squidGuard/db
rm -r *
wget 'http://www.shallalist.de/Downloads/shallalist.tar.gz'
tar -xvf shallalist.tar.gz
cd BL
mv * ..
cd ..
rmdir BL
/usr/sbin/squidGuard -C all
chown -R squid *
chown -R squid /var/log/squidGuard
rm shallalist.tar.gz
squid -k reconfigure
Run the following:
$ sudo chmod 750 /usr/sbin/update_squidguard_blacklist.sh
$ sudo ln -l /usr/sbin/update_squidguard_blacklist.sh /etc/cron.daily/update_squidguard_blacklist.sh
$ sudo nano -w /etc/squidguard.conf
Remove all lines from the file below "logdir /var/log/squidGuard" and paste in the following:
dest adv {
     domainlist adv/domains
     urllist    adv/urls
}

dest aggressive {
        domainlist      aggressive/domains
        urllist         aggressive/urls
        log             aggressiveaccess
}

dest alcohol {
        domainlist      alcohol/domains
        urllist         alcohol/urls
        log             alcoholaccess
}

dest anonvpn {
        domainlist      anonvpn/domains
        urllist         anonvpn/urls
        log             anonvpnaccess
}

dest costtraps {
        domainlist      costtraps/domains
        urllist         costtraps/urls
        log             costtrapsaccess
}

dest dating {
        domainlist      dating/domains
        urllist         dating/urls
        log             datingaccess
}

dest drugs {
        domainlist      drugs/domains
        urllist         drugs/urls
        log             drugsaccess
}

dest gamble {
        domainlist      gamble/domains
        urllist         gamble/urls
        log             gambleaccess
}

dest hacking {
        domainlist      hacking/domains
        urllist         hacking/urls
        log             hackingaccess
}

dest porn {
        domainlist      porn/domains
        urllist         porn/urls
        log             pornaccess
}

dest redirector {
        domainlist      redirector/domains
        urllist         redirector/urls
        log             redirectoraccess
}

dest sexeducation {
        domainlist      sex/education/domains
        urllist         sex/education/urls
        log             sexeducationaccess
}

dest sexlingerie {
        domainlist      sex/lingerie/domains
        urllist         sex/lingerie/urls
        log             sexlingerieaccess
}

dest spyware {
        domainlist      spyware/domains
        urllist         spyware/urls
        log             spywareaccess
}

dest violence {
        domainlist      violence/domains
        urllist         violence/urls
        log             violenceaccess
}

dest webmail {
        domainlist      webmail/domains
        urllist         webmail/urls
        log             webmailaccess
}

dest webtv {
        domainlist      webtv/domains
        urllist         webtv/urls
        log             webtvaccess
}

dest warez {
        domainlist      warez/domains
        urllist         warez/urls
        log             warezaccess
}
acl {
        admins {
                pass all
        }
        restricted {
                pass !weapons !warez !webtv !webmail !sexlingerie !sexeducation !redirector !porn !hacking !violence !aggressive !alcohol !anonvpn !costtraps !dating !drugs !gamble all
        }
        default {
                pass !spyware all
        }
}
Run the following command:
$ sudo echo 'redirect_program /usr/sbin/squidGuard' >> /etc/squid/squid.conf
$ sudo /usr/sbin/update_squidguard_blacklist.sh