/** function guifi_mac_validate($mac,&$form_state)
 * 
 * */
function guifi_mac_validate($mac, &$form_state)
{
    if ($form_state['clicked_button']['#value'] == t('Reset')) {
        return;
    }
    $m2 = $mac;
    unset($m2['#post']);
    guifi_log(GUIFILOG_TRACE, 'guifi_mac_validate', $m2['#parents']);
    guifi_log(GUIFILOG_TRACE, 'guifi_mac_validate', $form_state);
    // if empty,
    if (empty($mac['#value'])) {
        $pmac = null;
        // ...and have parents, take parent mac
        if (in_array($mac['#parents'][0], array('vlans', 'aggregations'))) {
            $macs = guifi_get_currentDeviceMacs($mac['#post']);
            $related = $mac['#post'][$mac['#parents'][0]][$mac['#parents'][1]]['related_interfaces'];
            guifi_log(GUIFILOG_TRACE, 'guifi_mac_validate MACS', $macs);
            guifi_log(GUIFILOG_TRACE, 'guifi_mac_validate RELATED', $related);
            if (is_array($related)) {
                $pmac = $macs[$related[0]];
            } else {
                $pmac = $macs[$related];
            }
        }
        // ... or ineterface mac, calculate from base device mac
        if ($mac['#parents'][0] == 'interfaces') {
            $iId = $mac['#post']['interfaces'][$mac['#parents'][1]];
            guifi_log(GUIFILOG_TRACE, 'guifi_mac_validate interface MAC', $iId);
            $pmac = _guifi_mac_sum($mac['#post']['mac'], $iId['etherdev_counter']);
        }
        // if mac set, set value in form
        if (!is_null($pmac)) {
            $mac['#value'] = $pmac;
            form_set_value(array('#parents' => $mac['#parents']), $pmac, $form_state);
            $form_state['rebuild'] = TRUE;
            guifi_log(GUIFILOG_TRACE, 'guifi_mac_validate (null NEW MAC)', $pmac);
        }
        //  if still empty, nothing to validate
        return;
    }
    $pmac = _guifi_validate_mac($mac['#value']);
    if ($pmac == FALSE) {
        form_error($mac, t('Error in MAC address (%mac), use 99:99:99:99:99:99 format.', array('%mac' => $mac['#value'])), 'error');
    } else {
        if ($pmac != $mac['#value']) {
            form_set_value(array('#parents' => $mac['#parents']), $pmac, $form_state);
            $form_state['rebuild'] = TRUE;
        }
    }
    return $mac;
}
function guifi_device_save($edit, $verbose = TRUE, $notify = TRUE)
{
    global $user;
    global $bridge;
    guifi_log(GUIFILOG_TRACE, 'function guifi_device_save()', $edit);
    $bridge = FALSE;
    $to_mail = array();
    $tomail[] = $user->mail;
    $log = "";
    $to_mail = array();
    // device
    // TODO : corretgir que agafi els midi fid de l'estructura qeu toca dins del edit
    // amb lo de sota els repliquem per poder-hi accedir directament
    if (in_array($edit['type'], array('radio', 'switch'))) {
        $edit['mid'] = $edit['variable']['model_id'];
        $edit['fid'] = $edit['variable']['firmware_id'];
    }
    if ($edit['type'] == 'radio') {
        if (!$edit['variable']['firmware']) {
            $firmware = db_fetch_object(db_query("SELECT id, nom as name " . "FROM {guifi_firmware} " . "WHERE id = '%d'", $edit['fid']));
            $edit['variable']['firmware'] = $firmware->name;
        }
    }
    // TODO REMOVE EXTRA  comprovar que no es serialitzen els camps de mid, fid, etc.
    if (!empty($edit['variable'])) {
        $edit['extra'] = serialize($edit['variable']);
    }
    // busquem el id de la configuracioUSC per aquests mid i fid
    $sql = db_query('SELECT id as uscid, enabled FROM {guifi_configuracioUnSolclic} WHERE mid=%d and fid=%d ', $edit['mid'], $edit['fid']);
    $configuracio = db_fetch_object($sql);
    $edit['usc_id'] = $configuracio->uscid;
    $ndevice = _guifi_db_sql('guifi_devices', array('id' => $edit['id']), $edit, $log, $to_mail);
    guifi_maintainers_save($ndevice['id'], 'device', $edit['maintainers']);
    guifi_funders_save($ndevice['id'], 'device', $edit['funders']);
    // Ensure we have all ports filled up to etherdev_max/optodev_max at model_specs
    $m = guifi_get_model_specs($edit['mid']);
    guifi_log(GUIFILOG_TRACE, 'function guifi_device_save(m)', $m);
    $interfaces = array_values($edit['interfaces']);
    guifi_log(GUIFILOG_TRACE, sprintf('switch %d saved, %d ports:', $ndevice['id'], $m->etherdev_max), $edit);
    if ($m->ethermax) {
        for ($port = 1; $port <= $m->ethermax; $port++) {
            if (!isset($interfaces[$port - 1])) {
                $ninterface = array('new' => true, 'interface_type' => isset($m->ethernames[$port - 1]) ? $m->ethernames[$port - 1] : $port, 'etherdev_counter' => $port, 'interface_class' => 'ethernet', 'device_id' => $ndevice['id'], 'mac' => _guifi_mac_sum($edit['mac'], $port - 1));
                guifi_log(GUIFILOG_TRACE, sprintf('inserting interface at %d:', $ndevice['id']), $ninterface);
                _guifi_db_sql('guifi_interfaces', null, $ninterface, $log, $to_mail);
            }
        }
    }
    guifi_log(GUIFILOG_TRACE, sprintf('device saved:'), $ndevice);
    $movenode = explode('-', $edit['movenode']);
    // radios
    $rc = 0;
    if (is_array($edit['radios'])) {
        ksort($edit['radios']);
    }
    $rc = 0;
    if ($edit['radios']) {
        foreach ($edit['radios'] as $radiodev_counter => $radio) {
            $keys['id'] = $ndevice['id'];
            $keys['radiodev_counter'] = $radiodev_counter;
            $radio['id'] = $ndevice['id'];
            $radio['radiodev_counter'] = $rc;
            if ($movenode[0]) {
                $radio['nid'] = $movenode[0];
            }
            $radio['model_id'] = $edit['variable']['model_id'];
            // check if device id has changed
            guifi_log(GUIFILOG_TRACE, sprintf('Checking radio (from:%d, to: %d): ', $radio['id'], $radio['to_id']), NULL);
            if (isset($radio['to_did'])) {
                // if radio has moved to another device:
                // -obtain the radiodev_counter of that device
                // -if has wLan/Lan interface:
                //   -convert to wlan
                //   -don't save it again at cable interfaces section'
                if ($radio['to_did'] != $radio['id']) {
                    $radiomoved = TRUE;
                    // -obtain the radiodev_counter of that device
                    $radio['id'] = $radio['to_did'];
                    $qry = db_query('SELECT max(radiodev_counter) + 1 rc ' . 'FROM {guifi_radios} ' . 'WHERE id=%d', $radio['to_did']);
                    $nrc = db_fetch_array($qry);
                    if (empty($nrc['rc'])) {
                        $nrc['rc'] = '0';
                    }
                    $radio['radiodev_counter'] = $nrc['rc'];
                    drupal_set_message(t('Radio# %id has been moved to radio# %id2 at device %dname', array('%id' => $rc, '%id2' => $radio['radiodev_counter'], '%dname' => guifi_get_hostname($radio['to_did']))));
                    // -if has wLan/Lan interface:
                    //   -convert to wlan if is not going a be the main radio
                    //   -don't save it again at cable interfaces section'
                    if ($radio['interfaces']) {
                        foreach ($radio['interfaces'] as $iid => $interface) {
                            if ($interface['interface_type'] == 'wLan/Lan') {
                                foreach ($edit['interfaces'] as $ciid => $cinterface) {
                                    // unset from cable section
                                    if ($cinterface['interface_type'] == 'wLan/Lan') {
                                        unset($edit['interfaces'][$ciid]);
                                    }
                                }
                                // if not radio#0, set as wLan at the other device
                                if ($nrc['rc']) {
                                    $radio['interfaces'][$iid]['interface_type'] = 'wLan';
                                }
                            }
                        }
                    }
                    $radio['interfaces'][$iid]['related_interfaces'] = $radio['to_did'] . ',' . $nrc['rc'];
                }
            }
            // save the radio
            $nradio = _guifi_db_sql('guifi_radios', $keys, $radio, $log, $to_mail);
            if (empty($nradio) or $radio['deleted']) {
                continue;
            }
            // interfaces
            if ($radio['interfaces']) {
                foreach ($radio['interfaces'] as $interface_id => $interface) {
                    $interface['device_id'] = $radio['id'];
                    $interface['mac'] = $radio['mac'];
                    $interface['radiodev_counter'] = $nradio['radiodev_counter'];
                    $log .= guifi_device_interface_save($interface, $interface_id, $edit['id'], $ndevice['nid'], $to_mail);
                }
            }
            // foreach interface
            $rc++;
        }
    }
    // foreach radio
    // Interfaces
    if (!empty($edit['interfaces'])) {
        // Set etherdev_counter (sort the interfaces by it)
        uasort($edit['interfaces'], 'guifi_interfaces_cmp');
        guifi_log(GUIFILOG_TRACE, 'Saving interfaces, interface:', $edit['interfaces']);
        $m = guifi_get_model_specs($edit['variable']['model_id']);
        $iCount = 0;
        // Save the interface
        foreach ($edit['interfaces'] as $iid => $interface) {
            $interface['device_id'] = $ndevice['id'];
            $interface['etherdev_counter'] = $iCount;
            if (in_array($edit['type'], array('switch'))) {
                $interface[interface_type] = $m->ethernames[$iCount];
            }
            $interface[interface_class] = 'ethernet';
            $iCount++;
            guifi_log(GUIFILOG_TRACE, sprintf('iid: %d, edit[nid]: %d, ndevice[id]: %d, interface:', $iid, $edit['nid'], $ndevice['nid'], $ndevice['nid']), $interface);
            if ($iid != 'ifs') {
                $log .= guifi_device_interface_save($interface, $iid, $edit['id'], $ndevice['nid'], $to_mail);
            }
        }
    }
    // vlans & aggregations
    foreach (array('vlans', 'aggregations') as $iClass) {
        if (!empty($edit[$iClass])) {
            // Save the interface
            foreach ($edit[$iClass] as $iid => $interface) {
                if ($radiomoved == TRUE) {
                    if ($interface['interface_class'] == 'wds/p2p') {
                        continue;
                    }
                }
                if (is_array($interface[related_interfaces])) {
                    $interface[related_interfaces] = implode('|', $interface[related_interfaces]);
                }
                $interface['device_id'] = $ndevice['id'];
                $log .= guifi_device_interface_save($interface, $iid, $edit['id'], $ndevice['nid'], $to_mail);
            }
        }
    }
    // ipv4s
    if (!empty($edit[ipv4])) {
        guifi_log(GUIFILOG_TRACE, 'guifi_device_save (ipv4s)', $edit['ipv4']);
        foreach ($edit['ipv4'] as $k => $ipv4) {
            if (is_numeric($k)) {
                guifi_log(GUIFILOG_TRACE, 'guifi_device_save (ipv4)', $ipv4);
                $iipv4 = db_fetch_array(db_query("SELECT * FROM {guifi_ipv4} WHERE ipv4 = '%s' ", $ipv4['ipv4']));
                $countqry = db_query("SELECT COUNT(*) FROM {guifi_ipv4} WHERE interface_id = %d", $iipv4['interface_id']);
                $count = db_result($countqry, 0);
                $ipv4_id = $count + 1;
                // TODO abans del save cal comprovar un id ipv4 disponbile, modificar-lo als links si en te, si es un link sense fils no ha de permtre triar uan interficie etherX,etc..
                //   db_query("UPDATE {guifi_ipv4} SET id = %d, interface_id = %d WHERE ipv4 = '%s' AND interface_id = %d",$ipv4_id, $ipv4['interface_id'],$iipv4['ipv4'],$iipv4['interface_id']);
            }
        }
    }
    $to_mail = explode(',', $edit['notification']);
    if ($edit['new']) {
        $subject = t('The device %name has been CREATED by %user.', array('%name' => $edit['nick'], '%user' => $user->name));
    } else {
        $subject = t('The device %name has been UPDATED by %user.', array('%name' => $edit['nick'], '%user' => $user->name));
    }
    //   drupal_set_message($subject);
    guifi_notify($to_mail, $subject, $log, $verbose, $notify);
    guifi_node_set_flag($edit['nid']);
    guifi_clear_cache($edit['nid']);
    guifi_clear_cache($edit['id']);
    variable_set('guifi_refresh_dns', time());
    return $ndevice['id'];
}