Esempio n. 1
0
void tool_app_t::cmac(const netlist::factory::element_t *e)
{
	auto v = plib::psplit(e->param_desc(), ",");
	pstring vs;
	for (auto s : v)
		vs += ", p" + s.replace_all("+", "").replace_all(".", "_");
	mac_out("#define " + e->name() + "(name" + vs + ")");
	mac_out("\tNET_REGISTER_DEV(" + e->name() +", name)");

	for (auto s : v)
	{
		pstring r(s.replace_all("+", "").replace_all(".", "_"));
		if (s.startsWith("+"))
			mac_out("\tNET_CONNECT(name, " + r + ", p" + r + ")");
		else
			mac_out("\tNETDEV_PARAMI(name, " + r + ", p" + r + ")");
	}
	mac_out("", false);
}
Esempio n. 2
0
/*
 * This function is an intermediate function that processes
 * any options before transmitting the actual frame. It parses
 * the frame's tx options and if its an indirect transfer, will
 * send it to the indirect queue. If the frame also requires an
 * ACK, it will buffer it in the retry queue so that the frame
 * can be re-sent in the case that the ack doesn't come.
 */
void mac_tx_handler(buffer_t *buf, address_t *addr, bool indir, bool ack_req, U8 dsn, U8 handle)
{
	if (indir) {
		mac_indir_add(buf, addr, ack_req, dsn, handle);
		return;
	}

	if (ack_req)
		mac_retry_add(buf, dsn, handle);

	mac_out(buf, ack_req, dsn, handle);
}
Esempio n. 3
0
void tool_app_t::header_entry(const netlist::factory::element_t *e)
{
	auto v = plib::psplit(e->param_desc(), ",");
	pstring vs;
	for (const auto &s : v)
		if (!plib::startsWith(s, "@"))
			vs += ", p" + plib::replace_all(plib::replace_all(s, "+", ""), ".", "_");
	mac_out("#define " + e->name() + "(name" + vs + ")");
	mac_out("\tNET_REGISTER_DEV(" + e->name() +", name)");

	for (const auto &s : v)
	{
		pstring r(plib::replace_all(plib::replace_all(plib::replace_all(s, "+", ""), ".", "_"), "@",""));
		if (plib::startsWith(s, "+"))
			mac_out("\tNET_CONNECT(name, " + r + ", p" + r + ")");
		else if (plib::startsWith(s, "@"))
			mac_out("\tNET_CONNECT(name, " + r + ", " + r + ")");
		else
			mac_out("\tNETDEV_PARAMI(name, " + r + ", p" + r + ")");
	}
	mac_out("", false);
}
Esempio n. 4
0
/*
 * Handle the rx events from the mac process. If the driver
 * receives a valid frame, it will send an event to the mac
 * process. The mac process will then call the event handler
 * which retrieves the frame from the rx queue and parses it.
 * Once parsed, it will be handled according to the frame type.
 * If its a command frame, it gets sent to the command handler,
 * a data frame gets sent to the next higher layer, etc...
 */
static void mac_eventhandler(process_event_t event)
{
	buffer_t *buf, *buf_out;
	mac_hdr_t hdr;
	mac_cmd_t cmd;
	bool frm_pend;
	mac_pcb_t *pcb = mac_pcb_get();
	mac_pib_t *pib = mac_pib_get();

	if (event == event_mac_rx)
	{
		DBG_PRINT("MAC_EVENTHANDLER: Rx event occurred.\n");

		buf = mac_queue_buf_pop();
		if (buf) {
			DBG_PRINT_RAW("\n<INCOMING>");
			debug_dump_buf(buf->dptr, buf->len);

			/* decode the packet */
			mac_parse_hdr(buf, &hdr);
			debug_dump_mac_hdr(&hdr);

			/*
			 * check if an ack is needed. if so, then generate
			 * an ack and queue it for transmission. the frm
			 * pending bit will be set for any frame coming from
			 * an address that has an indirect frame for it. this
			 * is against the spec, but it will speed up the ack
			 * transmission.
			 * NOTE: the ack response section may change due to the
			 * tight ack timing requirements.
			 */
			if (hdr.mac_frm_ctrl.ack_req)
			{
				BUF_ALLOC(buf_out, TX);
				DBG_PRINT("MAC: ACK Required.\n");
				frm_pend = mac_indir_frm_pend(&hdr.src_addr);
				mac_gen_ack(buf_out, frm_pend, hdr.dsn);
				mac_out(buf_out, false, hdr.dsn, 0);
			}

			/*
			 * process accordingly. if a scan is in progress,
			 * all frames except for beacon frames will be
			 * discarded.
			 */
			switch(hdr.mac_frm_ctrl.frame_type)
			{
			case MAC_COMMAND:
				if (pcb->mac_state != MLME_SCAN)
				{
					/*
					 * need to handle the case that this is an indirect
					 * transfer, which means that we need to stop the
					 * poll timer and send a status to the poll confirm.
					 */
					if ((pcb->mac_state == MLME_DATA_REQ) &&
					(hdr.src_addr.mode == SHORT_ADDR) &&
					(hdr.src_addr.short_addr == pib->coord_addr.short_addr))
					{
						ctimer_stop(&pcb->mlme_tmr);
						mac_poll_conf(MAC_SUCCESS);
					}

					mac_parse_cmd(buf, &cmd);
					mac_cmd_handler(&cmd, &hdr);
				}
				buf_free(buf);
				break;
			case MAC_BEACON:
				/* discard the beacon if we're not doing a scan */
				if (pcb->mac_state == MLME_SCAN)
				{
					mac_parse_beacon(buf, &hdr);
					mac_beacon_notify_ind(buf, mac_scan_descr_find_addr(&hdr.src_addr));
				}
				buf_free(buf);
				break;
			case MAC_ACK:
				mac_retry_ack_handler(hdr.dsn);

				/*
				 * we need to do some special ops depending on the
				 * state we're in if we get an ACK.
				 */
				if (pcb->mac_state == MLME_ASSOC_REQ)
				{
					if (pcb->assoc_req_dsn == hdr.dsn)
						ctimer_set(&pcb->mlme_tmr,
							   pib->resp_wait_time,
							   mac_poll_req,
							   NULL);
				} else if (pcb->mac_state == MLME_DATA_REQ) {
					if (hdr.mac_frm_ctrl.frame_pending)
						ctimer_set(&pcb->mlme_tmr,
							   aMacMaxFrameTotalWaitTime,
							   mac_poll_timeout,
							   NULL);
				}
				buf_free(buf);
				break;
			case MAC_DATA:
				if (pcb->mac_state != MLME_SCAN)
				{
					/*
					 * need to handle the case that this is an indirect
					 * transfer, which means that we need to stop the poll
					 * timer and send a status to the poll confirm.
					 */
					if ((pcb->mac_state == MLME_DATA_REQ)  &&
						(hdr.src_addr.mode == SHORT_ADDR) &&
						(hdr.src_addr.short_addr == pib->coord_addr.short_addr))
					{
						ctimer_stop(&pcb->mlme_tmr);
						mac_poll_conf(MAC_SUCCESS);
					}

					mac_data_ind(buf, &hdr);
				} else
					buf_free(buf);
				break;
			default:
				/* TODO: Add a statistic here to capture an error'd rx */
			break;
			}
		}
		/*
		 * there's a possibility that more than one frame is in the
		 * buffer. if they came in before this function gets executed.
		 * So process until the queue is empty.
		 */
		if (!mac_queue_is_empty())
		{
			while (process_post(&mac_process, event_mac_rx, NULL) != PROCESS_ERR_OK)
			{
				;
			}
		}
	}
}