diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..93ac46c263ebd958f70048477bc0700df6596dd0
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.pioenvs
diff --git a/platformio.ini b/platformio.ini
new file mode 100644
index 0000000000000000000000000000000000000000..41867f4b88b5abbea15139806197994bf429a363
--- /dev/null
+++ b/platformio.ini
@@ -0,0 +1,4 @@
+[env:uno]
+platform = atmelavr
+board = uno
+framework = arduino
diff --git a/src/PhoneNetwork.cc b/src/PhoneNetwork.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4df13bab73becbf611dd31e3714ddb2affeb60bc
--- /dev/null
+++ b/src/PhoneNetwork.cc
@@ -0,0 +1,83 @@
+#include "PhoneNetwork.hh"
+
+PhoneNetwork::PhoneNetwork() :m_state(WAITING), m_switch(), m_communication({-1, -1}) {
+}
+
+void PhoneNetwork::changeState(State targetState) {
+    switch(m_state) {
+        case(WAITING):
+            break;
+        case(DIALING):
+            break;
+        case(RINGING):
+            m_switch.stop_ring();
+            break;
+        case(COMMUNICATING):
+            break;
+    }
+
+
+    switch(targetState) {
+        case(WAITING):
+            Serial.println("Move to state WAITING\n");
+            m_switch.resetLines();
+            break;
+        case(DIALING):
+            Serial.println("Move to state DIALING\n");
+            m_communication.caller = m_switch.getActiveLine();
+            m_switch.setLineMode(DIALING, m_communication.caller);
+            break;
+        case(RINGING):
+            Serial.println("Move to state RINGING\n");
+            m_switch.setLineMode(RINGING, m_communication.called);
+            m_switch.start_ring();
+            break;
+        case(COMMUNICATING):
+            Serial.println("Move to state COMMUNICATING\n");
+            m_switch.setLineMode(COMMUNICATING, m_communication.called, m_communication.caller);
+            break;
+    }
+    m_state = targetState;
+}
+
+
+void PhoneNetwork::run() {
+    m_switch.refreshLinesState();
+    Serial.println(String(m_switch.m_linesState[0]) +
+                   String(m_switch.m_linesState[1]) +
+                   String(m_switch.m_linesState[2]));
+
+    switch(m_state) {
+        case(WAITING):
+            if(m_switch.phoneUnhooked()) {
+                changeState(DIALING);
+            }
+            break;
+
+        case(DIALING):
+            m_communication.called = m_switch.getDialedLine(m_communication.caller);
+            if(m_switch.dialedComplete(m_communication.called)){
+                changeState(RINGING);
+            }
+            else if (!m_switch.phoneUnhooked()) {
+                changeState(WAITING);
+            }
+            break;
+
+        case(RINGING):
+            m_switch.ring();
+            if(m_switch.phoneUnhooked(m_communication.called)) {
+                changeState(COMMUNICATING);
+            }
+            else if (!m_switch.phoneUnhooked()) {
+                changeState(WAITING);
+            }
+            break;
+
+        case(COMMUNICATING):
+            if(!m_switch.phoneUnhooked(m_communication.caller)){
+                changeState(WAITING);
+            }
+            break;
+    }
+}
diff --git a/src/PhoneNetwork.hh b/src/PhoneNetwork.hh
new file mode 100644
index 0000000000000000000000000000000000000000..d196a9e5f4ff567a8a9192c926e16cb4630deb86
--- /dev/null
+++ b/src/PhoneNetwork.hh
@@ -0,0 +1,26 @@
+#ifndef PHONE_NETWORK_HH_INCLUDED
+#define PHONE_NETWORK_HH_INCLUDED
+
+#include "constants.hh"
+#include "Switch.hh"
+#include "Arduino.h"
+
+struct Communication {
+    int called;
+    int caller;
+};
+
+class PhoneNetwork {
+public:
+    PhoneNetwork();
+    void changeState(State targetState);
+    void run();
+    Switch m_switch;
+
+private:
+    State m_state;
+    Communication m_communication;
+    int m_dialedNumber[NUM_SIZE];
+};
+
+#endif // PHONE_NETWORK_HH_INCLUDED
diff --git a/src/Switch.cc b/src/Switch.cc
new file mode 100644
index 0000000000000000000000000000000000000000..818c447d11f0b57ec881c284364d473d00d12c57
--- /dev/null
+++ b/src/Switch.cc
@@ -0,0 +1,193 @@
+#include "Switch.hh"
+
+//TODO: change initialisation to variable length table
+Switch::Switch(){
+    for(int i = 0; i<N_LINE ; i++)
+    {
+        m_linesState[i] = false;
+    }
+    refreshLinesState();
+}
+
+int Switch::searchPhoneBook(int number[NUM_SIZE]){
+  for(int line=0; line<N_LINE; line++){
+
+    bool match=true;
+    for(int i=0; i<NUM_SIZE; i++){
+      if(number[i] != linesNum[line][i]){
+        match=false;
+        break;
+      }
+    }
+
+    if(match)
+      return line;
+  }
+
+  return -1;
+}
+
+bool Switch::refreshLinesState(){
+  bool hasChanged=false;
+
+  for(int i=0; i<N_LINE; i++){
+    //Line is considered active if the maximum duration of time HIGH (inactive) is less than 10ms (50Hz).
+    //This is like that to prevent false detect introduced by the ringing.
+    unsigned long highTime = pulseIn(linePin[i].state, HIGH, 50e3);
+    bool active = (highTime==0) ? (!digitalRead(linePin[i].state)) : (highTime < 10e3);
+    //Serial.println(String(i) + " is high for "+String(highTime)+"us -> =0? "+String(highTime==0)+"  state: "+String(!digitalRead(linePin[i].state))+"  ==>"+String(active));
+    if(m_linesState[i] != active)
+      hasChanged = true;
+    m_linesState[i] = active;
+  }
+
+  return hasChanged;
+}
+
+int Switch::getDialedLine(int caller){
+  int called = -1;
+  int number[NUM_SIZE] = {0};
+
+  //called = (caller+1)%N_LINE;
+  for(int i=0; i<NUM_SIZE; i++){
+    number[i] = getDialedDigit(caller);
+    Serial.print(number[i]);
+  }
+  Serial.println();
+
+  called = searchPhoneBook(number);
+
+  return called;
+}
+
+
+bool Switch::dialedComplete(int line) {
+    return line != -1;
+}
+
+void Switch::start_ring() {
+  m_tps = millis();
+  digitalWrite(MASTER_RING, HIGH);
+}
+
+void Switch::ring(){
+//  bool ringing=false;
+
+//  ringing = millis() < (m_tps+RING_ON_TIME);
+//  if(millis() > (m_tps+RING_ON_TIME+RING_OFF_TIME)) {
+//    m_tps = millis();
+//  }
+//  digitalWrite(MASTER_RING, ringing);
+}
+
+void Switch::stop_ring() {
+    digitalWrite(MASTER_RING, LOW);
+}
+
+
+int Switch::getDialedDigit(int caller){
+  bool done=false;
+  unsigned long tps;
+  int number=0;
+
+  //Wait until begin of dialing
+  while(!digitalRead(linePin[caller].state));
+  delay(PULSE_WIDTH/8); //Force blind to avoid bouncing detection
+
+  while(not done){
+    tps=millis();
+
+    number++;
+
+    //HIGH state
+    while(digitalRead(linePin[caller].state) && not done)
+      done = millis() > (tps+PULSE_PAUSE);
+    delay(PULSE_WIDTH/8); //Force blind to avoid bouncing detection
+
+    //LOW state
+    while(!digitalRead(linePin[caller].state) && not done)
+      done = millis() > (tps+PULSE_PAUSE);
+    delay(PULSE_WIDTH/8); //Force blind to avoid bouncing detection
+  }
+
+  if(number == 10) number=0;
+
+  return number;
+}
+
+int Switch::getActiveLine(){
+  int active = -1;
+
+  refreshLinesState();
+
+  for(int i=0; i<N_LINE; i++){
+    if(m_linesState[i] == true)
+      active = i;
+  }
+  return active;
+}
+
+bool Switch::phoneUnhooked(int line) {
+    if(line != -1) {
+        return m_linesState[line] == true;
+    }
+
+    for(int i=0; i < N_LINE; i++) {
+        if(m_linesState[i] == true) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void Switch::setLineMode(State state, int lineA, int lineB){
+  if(lineA < 0)
+  {
+      return;
+  }
+  switch(state){
+    case WAITING:
+      digitalWrite(linePin[lineA].selector, LOW);
+      digitalWrite(linePin[lineA].ring, LOW);
+      digitalWrite(linePin[lineA].negative, LOW);
+      digitalWrite(linePin[lineA].positive, LOW);
+    break;
+    case RINGING:
+      digitalWrite(linePin[lineA].selector, LOW);
+      digitalWrite(linePin[lineA].ring, HIGH);
+      digitalWrite(linePin[lineA].negative, LOW);
+      digitalWrite(linePin[lineA].positive, LOW);
+    break;
+    case DIALING:
+      digitalWrite(linePin[lineA].selector, HIGH);
+      digitalWrite(linePin[lineA].ring, LOW);
+      digitalWrite(linePin[lineA].negative, LOW);
+      digitalWrite(linePin[lineA].positive, HIGH);
+    break;
+    case COMMUNICATING:
+      digitalWrite(linePin[lineA].selector, HIGH);
+      digitalWrite(linePin[lineA].ring, LOW);
+      digitalWrite(linePin[lineA].negative, LOW);
+      digitalWrite(linePin[lineA].positive, HIGH);
+
+      digitalWrite(linePin[lineB].selector, HIGH);
+      digitalWrite(linePin[lineB].ring, LOW);
+      digitalWrite(linePin[lineB].negative, HIGH);
+      digitalWrite(linePin[lineB].positive, LOW);
+    break;
+  }
+  delay(LINEMODE_DELAY);
+}
+
+void Switch::resetLines(){
+  for(int i=0; i<N_LINE; i++){
+    setLineMode(WAITING, i);
+  }
+}
+
+void Switch::printState(){
+  for(int i=0; i<N_LINE; i++){
+    Serial.println(String(i) + " is currently " + (m_linesState[i]?"active":"inactive"));
+  }
+  Serial.println();
+}
diff --git a/src/Switch.hh b/src/Switch.hh
new file mode 100644
index 0000000000000000000000000000000000000000..dc8ab770defd128c5dba02bd88f578fa429e6cb9
--- /dev/null
+++ b/src/Switch.hh
@@ -0,0 +1,33 @@
+#ifndef SWITCH_HH_INCLUDED
+#define SWITCH_HH_INCLUDED
+
+#include "constants.hh"
+#include "Arduino.h"
+
+class Switch
+{
+public:
+    Switch();
+    int searchPhoneBook(int number[NUM_SIZE]);
+    bool refreshLinesState();
+    int getDialedLine(int caller);
+    bool dialedComplete(int line);
+    void start_ring();
+    void ring();
+    void stop_ring();
+    int getDialedDigit();
+    int getActiveLine();
+    int getDialedDigit(int caller);
+    bool phoneUnhooked(int line = -1);
+    bool phonesHooked(int line = -1) return ! phoneUnhooked(line);
+    void setLineMode(State state, int lineA, int lineB=-1);
+    void resetLines();
+    int m_linesState[N_LINE];
+
+private:
+    unsigned long m_tps;
+
+    void printState();
+};
+
+#endif // SWITCH_HH_INCLUDED
diff --git a/src/constants.hh b/src/constants.hh
new file mode 100644
index 0000000000000000000000000000000000000000..77b9f52bc940c65f6301edfa6ca9d23512b52391
--- /dev/null
+++ b/src/constants.hh
@@ -0,0 +1,43 @@
+#ifndef CONSTANTS_HH_INCLUDED
+#define CONSTANTS_HH_INCLUDED
+
+//Standard
+#define RING_ON_TIME 1500 //ms
+#define RING_OFF_TIME 3500 //ms
+#define PULSE_WIDTH 100 //ms
+#define PULSE_PAUSE 700 //ms
+#define NUM_SIZE 3 //Number of digits in number
+
+//Hardware definition
+#define N_LINE 3
+
+//Pins definition
+#define MASTER_RING 19
+
+#define LINEMODE_DELAY 500
+
+typedef struct {
+  int selector;
+  int ring;
+  int negative;
+  int positive;
+  int state;
+} linepin_t;
+
+const linepin_t linePin[N_LINE] = {
+  {.selector= 2, .ring= 4, .negative= 6, .positive= 8, .state=14},
+  {.selector= 3, .ring= 5, .negative= 7, .positive= 9, .state=15},
+  {.selector=10, .ring=11, .negative=12, .positive=13, .state=16}
+};
+
+//Lines number
+const int linesNum[N_LINE][NUM_SIZE] = {
+  {5,8,8},
+  {2,3,6},
+  {5,9,6}
+};
+
+//Differents states of a line
+enum State {WAITING, RINGING, DIALING, COMMUNICATING};
+
+#endif // CONSTANTS_HH_INCLUDED
diff --git a/src/main.cc b/src/main.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4087f187fef481c489f2122ca26e9255a6481de5
--- /dev/null
+++ b/src/main.cc
@@ -0,0 +1,32 @@
+#include "Arduino.h"
+#include "PhoneNetwork.hh"
+#include "constants.hh"
+
+
+inline void setOutput(int pin){
+  digitalWrite(pin, LOW);
+  pinMode(pin, OUTPUT);
+}
+
+auto phoneNetwork = PhoneNetwork();
+
+void setup() {
+
+  //Setting up pins
+  for(int i=0; i<N_LINE; i++){
+    setOutput(linePin[i].selector);
+    setOutput(linePin[i].ring);
+    setOutput(linePin[i].negative);
+    setOutput(linePin[i].positive);
+    pinMode(linePin[i].state, INPUT_PULLUP);
+  }
+  setOutput(MASTER_RING);
+  phoneNetwork.m_switch.resetLines();
+
+  Serial.begin(115200);
+  Serial.println("Small RTC, at your service !");
+}
+
+void loop() {
+  phoneNetwork.run();
+}