- Content originally developed by Patrick Lam, modified by Jeff Zarnett - Original lecture notes available at: https://github.com/jzarnett/ece155 - Notes written by Melissa Tedesco #L19: Debugging# ##Debugging Strategy## 1. Observe a failure 2. Invent a hypothesis as to failure cause 3. Use hypothesis to make predictions 4. Test hypothesis by experiments - If experment satisfies the predictions, refine hypothesis - Else, create alternate hypothesis 5. Repeat 3-4 **Bug Localization:** Attempt to localize bug to within a subsystem ##Debugging Tactics## - *Code review:* think about what program is supposed to do vs what it's actually doing - *Code instrumentation:* put print statements (or equivalent) in code so you can observe what parts of the code is running, and the state of the variables - *Single-step execution:* can step through code in a debugger line-by-line and manually inspect the program state; only effective once bug is localized down to a small area ###Logging for Android Development### - System.out.println() does not work for Android. Instead, use: ``` Log.d("tag", "i=" + i);``` - use different levels (e.g. ```Log.d, .i., .v, .wtf``` Can filter by level or tag) - can also rely on Assertions ###Single-step execution### - programs can be really big, and you don't want to run through the entire program every time - so you add in *breakpoints* before lines you think might be faulty. Then when you reach the breakpoint, you can single-step through the lines - Breakpoint Types: - *line breakpoints:* halt program execution at a particular line (can be conditional) - *exception breakpoints:* halt program execution and load the debugger when the program throws a particular exception - *watchpoints:* halt program execution when a particular memory location changes (or is accessed) - *method breakpoints:* halt program execution upon entry or exit from a particular method ##Types of Bugs## ###The Common Bug### - in the source code, behaves predictably - sometimes result of ambiguous specification, something not tested, or simply programmer error ###The Sporadic Bug### - strikes predictably when a test case is executed - not so consistent, but can be lured out if you are careful (reproducible given proper test case) ###Heisenbugs### - hides when you try to find it; difficult to reproduce - usually one of the following problems: - **Race Condition** program behaviour depends on order of completion of certain tasks - **Memory Errors** memory access problems - reading an uninitialized value, reading off the end of an array, reading an area of memory after it's been freed, etc. ###Secret Bugs### - customer is using the software and encounters a bug, but don't want to tell you about it because it involved confidential info - can try to reproduce the problem in house - can create test data, or ask customer for anonymized set of test data ###Configuration or Environment Bugs### - nothing wrong with the software, but the environment it's run in (e.g. user may not have permissions necessary for the program to run as expected) - can change software to handle the situation more gracefully ###Hardware Bugs### - lots of possibilities for hardware bugs in embedded systems ###The Not-A-Bug### - when you are examining the bug, you find it's not actually a bug - the system is performing as spec says it should #L20: Debugging II# ##Creating Test Cases## - after finding a way to reproduce a bug consistently, should be able to make a unit test of it; should be added to regression tests ##Writing Testable Code## - consistent style - good variable names - spread out code - use temporary variables for complex expressions - make discrete, testable methods instead of larger, harder-to-test method - comments -> explain WHY something is being done. Try to write "self-documenting code"; wrong comments are worse than no comments - documentation - create logs ##The Golden Rules of Debugging## 1. Understand the requirements 2. Make it fail. 3. Simplify the test case 4. Look at the right error message 5. Check the environment. 6. Separate facts from interpretation 7. Divide and conquer 8. Use the right tool. (not just debugger - memory debugger, log files, static analysis tools, etc.) 9. Make one change at a time 10. Keep an audit trail. 11. Get a fresh perspective. 12. If you didn't fix it... 13. Create a regression test. #L22: Debugging III# ##Debugging Parallel Programs## - race conditions can often occur in multi-threaded programs because multiple threads are using the same methods, and the order in which the functions are called are not what you might expect - e.g. two threads are setting the X and Y co-ordinates of an object Location - Thread 1 executes ``` location..setX(5); location.setY(7); ``` - Thread 2 executes ``` location.setX(10); location.setY(0); ``` - desired behaviour for location to be set to (5,7) and then (10,0) but that may not happen. - these kind of race conditions can also come about out of interrupts - solution: use lock-modify-unlock, just like the version control system ``` lock(location); location.setX(5); location.setY(7); unlock(location); ``` ###Locking and Unlocking in Java### - Java uses the ``` synchronized ``` keyboard to implement lock-modify-unlock behaviour - all synchronized blocks synchronized on the same object can only have one thread executing inside the synchronized area at the same time - can apply the keyboard to: - instance methods - static methods - code block methods - not necessary to make the entire block synchronized - in fact, you want to minimize the synchronized section as much as possible - given an object ``` s ``` shared between multiple threads, use this syntax to add a synchronized code block: ``` synchronized(s) { s.count++; //or whatever code you want } ``` - when a thread reaches this line, the ```this``` thread will try to get the lock. If it can't, it will wait until the owner releases it ##Debugging Embedded Systems## - debugging embedded systems can be difficult due to the limitations of the system - want to separate the hardware debugging from software debugging - for software debugging: use a hardware simulator - for hardware debugging: test drivers and a test harness - after integrating the hardware and software, more challenges: - *fault (bug) localization*: Is the problem with hardware or software? And where in each component? - *need for instrumentation*: need to get diagnostic info somehow. Probably can't use ```print``` statements. And you need to determine state of the hardware. At the interface between HW/SW, you can use a logic analyzer - *software breakpoints are hard*: when you use a breakpoint, software stops but hardware continues to run ###Strategies### - **simulate**: try to reproduce problem in simulated environment (usually gives you console output and ability to set breakpoints / walk through code) - **use your actuators**: e.g. use LEDs to input info about state of system, or beep codes, or use error codes on a numeric display - **add debugging functions**: can add specific debugging functions to input specific data into system - **standard interfaces**: e.g. JTAG; standard interface for testing and I/O in many embedded systems #L21: Planning# **Estimation:** An informed guess, based on facts, about the amount of resources a task will need **Planning:** Figuring out *how* to do a project; dividing the project into a set of small, related tasks **Scheduling:** Proposing order in which to carry out the plan ##Planning## ###Vision and Scope Document## - helps make sure that all the people who care about the project are on board with the proposed project (like a preliminary requirements gathering) - summarizes the design problem, stakeholders, users, risks, assumptions, and desired features of a solution - identifies the features that will be involved - discusses feature might expect but won't be included - summarizes agreed-upon expectations about the project's scope ###Project Plan### - lists the work to be done on the project, as well as who is to do the work - has the following components: ####Statement of Work#### - describes all work products to be produced and IDs who will do the work - includes: - a list of all product features - a description of each deliverable that will be developed - estimated effort required for each deliverable, if known ####Resource List#### - lists all resources required for a project and summarizes the availability of the resources - *resource:* person, hardware component, software license, a room, or anything else necessary but limited in availability ####Work Breakdown Structure#### - describes all project activities required to complete the project, including intermediate deliverables - should be revised over time. Using version control for this doc would be appropriate ####Project Schedule#### - estimates start and end times of all project activities ####Risk Plan#### - **risk:** potential threat to successful completion of project - risk plan describes anticipated risks, the likelihood of their occurrence, and how they might be handled ##Estimates## - these can help with coming up with accurate time estimates: - accurate WBS - effort estimate for each task listed in WBS - a list of assumptions made during effort estimate - consensus among project team that estimates are reasonable ##Estimation Techniques## ###Wideband Delphi Process### - choose an estimation team and moderator - hold a kickoff meeting to develop a WBC, list of assumptions, unit of estimation - allow estimation team to independently prepare estimates - hold an estimation session - moderator requests estimates, attempt to achieve consensus - consists of different rounds. Moderator plots effort estimates, they discuss assumptions, clarify, revise estimates. They submit estimates again and the moderator plots them - over the rounds, the estimates by the team members should start to converge (this is *convergence* in the WDP) - assemble final list of estimates and assumptions - review ###PROBE### - obsessively track how long it took to do things in the past, and use linear regression to estimate how long it'll take in the future ###COCOMO II### - feed in a number of guesses about your project's scope, apply a formula full of fudge factors, and get an estimate of size and effort ###The Planning Game### - consists of two phases: release planning and iteration planning - **release planning:** team meets every week to plan the immediate future of the project - **iteration planning:** team divides requirements into sets of tasks to be completed, and assigns tasks #L23: Code Reviews# ##Reviews## **informal review:** written or verbal review requested by a dev **formal review:** written review conducted by a team leader or mod for the purpose of IDing, documenting and fixing defects ###Types of Reviews### - **desk check:** informal, author distributes their work to peers for feedback - **walkthrough:** informal, meeting moderated by author - **inspection:** formal, meeting guided by moderator. Produces a log of ID'd defects - **code review:** software inspection where defects in source code are ID'd, logged, and perhaps corrected ####Steps for Formal Inspections#### - preparation: distribute printout of project before meeting, with checklist of what to review - overview: moderator provides an overview of the work product - page-by-page review: moderator walks the team through the work product page-by-page and logs defects - rework: after meeting, author goes through lists and fixes them - follow-up: inspection team verify the author fixed defects - approval: inspection team approves work ####Code Review#### - examines source code (or patches to source code) - can examine all code, or use "sampling"; when sampling, here are places to look: - source code only one person has the expertise to maintain - tricky algorithms that are susceptible to defects - source code that calls difficult-to-use libraries - code written by inexperienced developers - functions that could fail catastrophically if a defect is present #L24: Software Lifecycle Models & Tactics# ##High-Level Overview## - a general list of steps in the software design process: - Problem Definition - Requirements Development - Project Planning - High-Level Design - Detailed Design - Coding and Debugging - Integration Testing - System Testing - Corrective Maintenance ##Software Development Models## ###[Waterfall Model](http://www.cleverworkarounds.com/wp-content/uploads/2008/06/image5.png)### - highly sequential - cannot progress to next stage without finishing the current - advantages: it fixes requirements early, models like this SHOULD identify problems early in design process - in reality, it kinda sucks. No one actually uses it ###Concurrent Engineering### - like waterfall, but you start working on the next stage as soon as you have something to work with - advantages: might need less documentation, projects need not be divided into smaller projects, testing could reveal problems earlier - disadvantages: milestones aren't as clear, progress is difficult to track, poor communication can lead to disaster given parallel design stages ###[V-Model](http://upload.wikimedia.org/wikipedia/commons/e/e8/Systems_Engineering_Process_II.svg)### - another variant of the waterfall model - goal is to link between the early and late stages (e.g. Verification and validation link to requirements and architecture) - very similar to waterfall, shares advantages and disadvantages ###[Spiral Model](http://upload.wikimedia.org/wikipedia/commons/e/ec/Spiral_model_%28Boehm,_1988%29.svg)### - project is split into a number of smaller projects - go through the stages for that small project, then again, again, etc. - risk-oriented - each sub-project addresses 1+ risks - advantages: addresses biggest risks first, when changes are least expensive; progress is visible to customer + managements - disadvantages: may not be possible to identify sub-projects ##Software Development Tactics## ###Scrum### - work is broken down into a series of *sprints* (short cycles of a specified length, like 30 days) - dev team reviews the items in the backlog at the beginning of the spring and sets goals - daily meetings to keep on track during sprint - advantages: short iterations - lots of opportunity for input and feedback; daily meetings = lots of co-ordination; encourages breaking software down into manageable units - disadvantages: does not scale to large teams; daily meetings = excessive overhead; at the deadline, development ends whether the code is finished or not ###[Test-Driven Development](http://upload.wikimedia.org/wikipedia/commons/9/9c/Test-driven_development.PNG)### - when adding a new feature, dev writes tests and then the feature is developed until the test passes ###Behaviour Driven Development### ###Extreme Programming### ###Kanban### #L25: Refactoring# - refactoring is the changing of code to improve code quality (making it easier to understanding) using local, semantics-preserving changes to the code - **local:** refactoring should only change the parts of the program that you're re-factoring. - **semantics-preserving:** the behaviour of the refactored code should be identical to the behaviour of the original code ##Types of Refactoring## - **composing methods:** change what code belongs to which method - **moving features between objects:** put fields, methods, classes in different places - **organizing data:** change how data is stored - **simplifying conditionals:** make your ```if``` statements easier to understand - **making method calls simpler:** change how methods relate to each other - **generalizations:** similar to moving features, but related to the inheritance hierarchy ##Refactoring Algorithm## 1. Create unit tests (if needed) 2. Run unit tests 3. Make changes 4. Re-run unit tests 5. Evaluate results ##Lists of Refactoring## - techniques that allow for more abstraction: - **encapsulate field:** force code to access field with getter and setter methods - **generalize type:** create more general types to allow for more code sharing - **replace conditional with polymorphism:** use inheritance and virtual dispatch instead of a conditional - techniques for breaking code apart into more logical pieces - **extract method:** pull out part of a larger method into a new method - **extract class:** moves code from existing class into a new class - **extract variable** - **extract magic constant** - techniques for integrating code that's needlessly spread apart: - **inline method:** integrate a copy of the body of a method into its calling method - **inline class:** put all of the fields and methods of a class into another class and erase the original - techniques for improving names and location of code - **move method/field:** move to a more appropriate class or source file - **rename method/field:** change to a name that better reveals its purpose - **pull up:** in OOP, move to a superclass - **push down:** in OOP, move to a subclass ##Design Antipatterns## ###The Blob### - has too much of the code and logic in one class - solution: extract methods and classes so that responsibilities are properly distributed ###Lava Flow### - dead code that is useless, but no one wants to remove because they're afraid of breaking something - solution: remove. Test with unit tests that nothing broke. If something did, revert back ###Functional Decomposition### - this happens when non-OOP devs design and implement an application in OOP - can be very complex because the devs will devise "clever" ways of replicating their methods in an OOP architecture - solution: extract classes, merge duplicate code, create methods such that there is defined structure ###Copy-and-Paste Programming### - code reused by copy and pasting leads to maintenance problems - could have duplicate methods - solution: extract common elements and make them generic ###Poltergeists### - classes with very limited roles and effective life cycles, aka objects that pop in, do one thing, then vanish - solution: inlining their functionality into other objects ###Golden Hammer### - when people try to shoe-horn a specific architecture as the solution to everything - solution: refactor the code to a more appropriate architecture or design ###Exceptions as Control Flow## - exceptions should not be part of the normal flow of the program - solution: instead of ```try-catch``` block where the catch block does something, refactor so the condition is checked in advance ###Spaghetti Code### - program that contains little or no structure - solution: all refactoring techniques, until some structure is formed #L26: Interval & Watchdog Timers# ##Timers## - used to perform a task occasionally or reset a system that's stuck ###Interval Timers### - appropriate for recurring timers - can use ```Handler``` to implement interval timers: ``` Handler h = new Handler(); Runnable r = new Runnable() { public void run() { //execute the task h.postDelayed(this, delayInMS); }; h.postDelayed(r, delayInMS); ``` - then you can cancel an upcoming task like so: ```h.removeCallbacks(r);``` ###True Interval Timer - ```Handler``` isn't a **true** interval timer, because it doesn't interrupt the processor should - can simulate an interval timer more closely with the ```Timer``` class, which runs in a different thread - however, other threads can't do updates to the UI ``` Timer t = new Timer(); t.schedule(new TimerTask() { @Override public void run() { runOnUiThread(timerTick); } }, firstDelayMS, repeatIntervalMS); Runnable timerTick = new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), "ding!", Toast.LENGTH_SHORT).show(); } }; ``` ###Watchdog Timers### - watchdog timers can observe that a system appears to be stuck and take some action - after setting up a watchdog timer, the system needs to indicate before the limit of the timer, that everything is okay (at which point the timer is reset) ####Implementing Watchdogs with Interval Timers#### - set the timer interval to be the largest allowable time for task to take. Start timer - if the timer fires, the tasks took too long - timer event handler should execute, so it can deal with the situation (for instance, by killing the task) #L27: Verification & Validation; SW Maintenance# - **verification:** assume a set of requirements and establish that the product satisfies the requirements - forms: testing, static analysis (computers pore over the code or design) - **validation:** making sure the requirements are the right ones - forms: beta testing ##Formal Methods## - a bunch of techniques for verifying that code conforms to a specification (aka, code performs the way you want it to be) ##Software Maintenance## - **corrective maintenance:** correct known defects - **adaptive maintenance:** keep a software product usable in a changing environment - **perfective maintenance:** improve performance or maintainability - **preventive maintenance:** correct faults in the program before they manifest #L28: Simulation# ##Why Simulate?## - system may not exist yet (e.g. proposed plane design) - system may be costly to use - system may be dangerous to use (dangerous to make a mistake on) - system may be disrupted by use - don't have enough access to system ##Simulation Models## ###Continuous vs Discrete Simulation## - continuous models represent a system with continuously changing state variables - might be used to simulate an analog circuit - digital models represent a system with discrete state changes - might be used to simulate a digital circuit ###Dynamic vs Static Simulation### - dynamic models represent a system as it evolves over time; recomputes state of system - static models represent a system at one point - you feed it some conditions and it tells you the result - useful for what-if simulations ("If I sell these at $4, how many will I sell?") ###Deterministic vs Stochastic Simulation### - deterministic models exactly computers the simulated state of the system at every step - subject to inaccuracies in the calculations - stochastic models use randomness to estimate the expected behaviour without computing the behaviour of each particle - relies on the underlying randomness of the system components #L29: Software Statistics# - if you want to study this topic, do it on your own. I'm not writing notes for it. #L30: Software Bricolage; Licenses# ##Software Bricolage## - in the real world, you pretty much never have to *actually* start a project from scratch. - given a goal to accomplish, follow these steps: 1. **Forage** - look for software that does what you want - software may be in a number of different languages - if what you found adequately meets your needs, wooo, you're done 2. **Tinker** - figure out what the software actually does, experiment with it, modify it - if what you have isn't what you need, repeat between steps 1 and 2 3. **Weld** - combine the pieces you've foraged - potential real-world problems - missing and conflicting dependencies - impedance mismatches (Software A produces output in XML, software B requires input in CSV. Must be bridged) 4. **Grow** - start to actually build the code you need 5. **Doubt** - avoid re-inventing the wheel - be familiar with what's in the libraries; ask authors of libs 6. **Refactor** - clean up your code and make it more general - improve interactions between your code and the outside code ##Software Licenses## - software licenses tell you how a piece of software can be used or distributed ###Types of Licenses### - **Proprietary Licenses:** - They're all different. The rights you have are specifically defined; that's all you have. - **GPL (GNU General Public License):** - open source software license; a copyleft example of copyright law - ensures that code can be used, copied, modified and redistributed freely - can't use this code in propertiary programs -> all changes made must be licensed under GPL or a compatible license - **LGPL (Lesser GPL):** - intended for software libraries - the code (once compiled) can be linked to a propertiary program without having to re-license the program - the library code itself, must follow restrictions as if it were GPL - **BSD:** - open source license, very permissive - effectively allows any use of the code, but disclaims liability - **Mozilla License:** - open source license from Mozilla Group - allows for "mixed" source code - any file license directly under the Mozilla license must be available in source form, but not all files in a program must be licensed under the Mozilla license - **Public Domain:** - no copyright owner, can be used by anyone for anything #L31: Android IV# ##Networking## ###Performing Networking Operations### - need these permissions to do any networking: ``` <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> ``` - to check if user is connected to a network: ``` ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); if (networkInfo != null && networkInfo.isConnected()) { ... // Do useful work } ``` - since networks are unstable and can take a long time, should not perform network operations on main thread; instead, use a background task (class: ```ASyncTask```) - here is an example of a defined ```ASyncTask```: ``` private class DownloadWebpageTask extends AsyncTask<String, Void, String> { @Override protected String doInBackground(String... urls) { // params comes from the execute() call: params[0] is the url. try { return downloadUrl(urls[0]); } catch (IOException e) { return "Unable to retrieve web page. URL may be invalid."; } } // onPostExecute displays the results of the AsyncTask. @Override protected void onPostExecute(String result) { textView.setText(result); } } ``` - when an asynchronous task is executed, it goes through 4 steps: 1. ```onPreExecute()```, invoked on UI thread before task is executed. Normally used to set-up the tasks (e.g. show a progress bar in the UI); optional 2. ```doInBackground(Params...)```, invoked in background thread after ```onPreExecute()```; used to perform background computation. Result of computation must be returned by this step and will be passed back to the last step; step can also use ```publishProgress(Progress...)``` to publish 1++ units of progress on UI thread 3. ```onProgressUpdate(Process...)```, invoked on the UI thread after a call to ```publishProgress(Process...)```. Used to display any form of progress in UI; optional 4. ```onPostExecute(Result)```, invoked on UI thread after the background computation finishes - to cancel a task, you can call ```cancel(boolean)```, which makes ```isCancelled()``` return true; ```doInBackground``` should check to see if task has been cancelled (and then stop doing its thing) - after task is cancelled, ```onCancelled``` is called instead of ```onPostExecute``` ###Actually Downloading a Page### ``` // Given a URL, establishes an HttpUrlConnection and retrieves // the web page content as a InputStream, which it returns as // a string. private String downloadUrl(String myurl) throws IOException { InputStream is = null; // Only display the first 500 characters of the retrieved // web page content. int len = 500; try { URL url = new URL(myurl); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(10000 /* milliseconds */); conn.setConnectTimeout(15000 /* milliseconds */); conn.setRequestMethod("GET"); conn.setDoInput(true); // Starts the query conn.connect(); int response = conn.getResponseCode(); Log.d(DEBUG_TAG, "The response is: " + response); is = conn.getInputStream(); // Convert the InputStream into a string String contentAsString = readIt(is, len); return contentAsString; // Makes sure that the InputStream is closed after the app is // finished using it. } finally { if (is != null) { is.close(); } } } // Reads an InputStream and converts it to a String. public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException { Reader reader = null; reader = new InputStreamReader(stream, "UTF-8"); char[] buffer = new char[len]; reader.read(buffer); return new String(buffer); } ``` ###Cloud Sync and Merge Conflicts### - can sync you app with the cloud so user data is not lost; Google provides an API for small amounts of data for storing user preferences, high scores, notes, etc. - I'm not going to show the code for using it - you might want to check out the lectures notes for that - it's possible that you can end up with sync conflicts (user has 2+ devices, >1 of them try to save data to cloud) - some simple solutions to follow: - Newer is better: In this case, choose to store the timestamp in the cloud save data - Value Judgement: Choose based on what is defined as "best" (e.g if saving high scores, keep the highest score) - Merge: Merge by union (e.g. if data represents set of levels unlocked, resolved data is the union of the two conflicting sets) #L32: Software Architecture Patterns# ##Software Architecture## - general, re-usable solution on structuring a piece of software - all pieces of software contain: - logic: the software does some work - data: stores and/or retrieves data - UI: presents and accepts info/commands ##The Monolith## - application in which all elements are combined into a single, self-contained program - no defined modules, no components, no clear lines between different parts of the program - simple to understand, faster to write - but difficult to maintain - things become interconnected and can become difficult or impossible to change ##Client-Server Architecture## - two roles in the system - client and server - and they communicate with a request-response message pattern - client sends a request to the server, server sends a response back - server: logic and data elements; client: UI ##Three-Tier Architecture## - similar to client-server but UI, logic and data are all separate - *presentation tier:* top-most level; UI - *logic tier:* co-ordinates application, processes commands, makes logical decisions and evaluations, perform calculations, etc. Also moves data between the two surrounding layers - *data tier:* information is stored and retrieved from a database or file system - it is possible for logic tier to be further divided (n-tier architecture) - note: client-server interaction could exist between any two adjacent tiers in the system ##Model-View-Controller Architecture## - divides the software application into three different parts - Model, View, and Controller - **Model:** holds represent knowledge (e.g. an object, or structure of objects), and the methods/functions; tells the view and controller if object has been updated - **View:** a representation of the model; can have multiple views - **Controller:** accepts input and converts it into commands for the model or view - [a representation of MVC control flow](http://upload.wikimedia.org/wikipedia/commons/a/a0/MVC-Process.svg) ##Modular Architecture## - the tiers, or the client and server, might be too complicated to build in a monolith - instead of having one monolith "server" program, you might create it out of separate modules that are responsible for different aspects of the server work - that way, modules may be replaced or upgraded independently of others #L33: Software Communication Patterns# - looking at the architecture of communication within programs ##Pipes and Filters Architecture## - **pipe:** takes input, performs action on the data, and outputs the result - can transform data - **filter:** takes input, and will either accept it (appear in the output) or reject it (no output appears) - read-only: do not change data - various pipes and filters can be combined to form a *pipeline* ##Blackboard Architecture## - has a common knowledge base and set of agents who work on the base - **Software Agents/Knowledge Sources:** the agents of the system - **Blackboard:** the shared repository of problems and partial solutions; the input and outputs from the agent - **Moderator:** controls the flow of access to the system so agents do not interfere with each other - not applicable to a lot of problems, but can be used to solve problems that would otherwise not be solvable ##Publish-Subscribe Architecture## - communication takes place by passing messages - **Publisher:** sender of a message; does not know who the receivers are - **Subscribers:** receivers; register their interest in certain kinds of messages without knowledge of any publishers - **Brokers:** (optional) connects the publishers and subscribers indirectly; publisher can publish the message here so the subscribers can collect it at their convenience - filtering messages: - **Topic-Based:** have a list of topics, publishers write in these topics, subscribers listen to that channel - e.g. I create an ECE 155 channel, and I id that a message is intended for that channel - **Content-Based:** messages are delivered to a subscriber if the content matches what they're looking for - e.g. a subscriber might get sent all messages containing the text "ECE 155" ##Peer-to-Peer Architecture## - the different nodes (computers or programs) in the network both supply and receive resources - major advantage is that their ability to serve content increases as more requests come in #L34: Security# ##Properties of Embedded Systems## - **Physical Access:** a lot of security measures are easily defeated given physical access to a device; many embedded systems are, well, embedded in the world and not kept under security - contrast an ATM to a server - **Limited Resources:** embedded devices have limited processing power to spend on running security checks - **Hard to Update:** may be difficult or impossible to update an embedded system to patch a security vulnerability - **Connectivity:** lots of embedded devices are connected (to the internet or other systems), which provides a gateway for attack ##Attacks on Embedded Systems## - **Physical Tampering:** a user with physical access to the device could open it up and read data, attach listening devices, etc. - **Denial-of-Service Attack:** system is flooded with requests that overwhelm its ability to respond - can take the form of an *exhaustion attack*, where the attacker causes the system to run its battery down faster - **Sensor Tampering:** damaging or disabling the sensors to bypass the system (e.g. feeding in false input, or smashing a camera) ##Countermeasures## - **Encryption:** encrypt all sensitive data so attackers can't read it, even if they have access to the device - **Defeating DOS Attacks:** defeat to defend all kinds of attacks, but can be mitigated - limit the rate at which requests are entered (e.g. can only send x messages in n seconds) - **Monitoring:** might have secondary software processes to check on the health and status of the system, and its sensors/actuators ###Encryption and Salting### - given a RSA encryption system, it can be detected when the same message is sent twice - solution: randomize every instance of encryption with an additional message (Initialization Vector) that can be passed along in plaintext - example: password salting - in old UNIX systems, usernames and hashed passwords were stored in ```/etc/passwd```; if two users had the same password, you could tell - now, they add and display a "salt" (a randomly generated string, unique to each user), which is added to the password when it is hashed - so if my password was butts123, and my salt was q3j4oi329nfd, the input to the encryption function would be "butts123q3j4oi329nfd" ##Authentication vs Authorization## - **Authentication:** verifies who the user is; can be done with un/pw, fingerprint scan, key card, etc. - **Authorization:** verifies what the user is allowed to do ##Access Control## - operating systems control access to files as part of the file system ###Unix-Style Permissions### - every file has an owner, and a group - separate permissions can be set for the owner, the group, and others - 3 basic permissions: read, write, execute - permissions represents using 10 bits: - 1 directory bit - set if the file is actually a directory - 3 bits for owner permissions - read, write, execute (each bit set to 1 if that action is allowed) - 3 bits for group permissions - 3 bits for others permissions - permissions can be displayed as 10 characters, where r=read, w=write, x=execute, and - = permission, and d= directory - example: -rwxrw-r-- - it's a file; owner can read-write-execute; group can read-write, others can read - can also be displayed as a 3-bit octal number, where r=4, w=2, x=1; add the values of the permissions granted - example: 752 - owner can rwx, group can rx, others can r ###Access Control Lists### - in SELinux (Security Enhanced Linux) and NTFS (Windows NT File Systems), files are protected by access control lists - each file can have as many security descriptors as we like, which specifies the permissions a specific user or group can have - permissions are not limited to rwx ###Role-Based Access Control### - in RBAC, a set of roles is created, users are assigned roles, and access is granted or denied based on the roles a user has - assignment is simpler: if there are many files that should only be accessed by sysadmin, easier to add a new user to the sysadmin role than to explicitly add that user to each file's ACL - can also have relation between roles (e.g. Engineer may have all the permissions as Technicians, and more, therefore set up the system so that the engineer role subsumes the technician role) ##Malicious Software## - **Viruses:** propagates by inserting itself into and becoming part of another program; often attached to executables - **Worms:** like viruses in that they spread copies and can do damage, but need no hosts - it's a standalone piece of software; exploit a vulnerability of the system and spread on its own - **Trojans:** users are tricked into installing it in their system; usually consist of client and server (victim installs server, attackers controls remotely with client) #L35: Library Card#