📄 sicslowmac.c
字号:
* * \return Integer denoting success or failure. * \retval 0 Failure. * \retval 1 Success. * * The data request primitive creates the frame header based * on static and dynamic data. The static data will be refined * in phase II of the project. The frame payload and length are * retrieved from the rime buffer and rime length respectively. * * When the header and payload are assembled into the * frame_create_params structure, the frame is created * by a call to frame_tx_create and then transmited via * radio_send_data. *//*---------------------------------------------------------------------------*/intsicslowmac_dataRequest(void){ _delay_ms(SICSLOW_CORRECTION_DELAY); /* create structure to store result. */ frame_create_params_t params; frame_result_t result; /* Save the msduHandle in a global variable. */ msduHandle = rimebuf_attr(RIMEBUF_ATTR_PACKET_ID); /* Build the FCF. */ params.fcf.frameType = DATAFRAME; params.fcf.securityEnabled = false; params.fcf.framePending = false; params.fcf.ackRequired = rimebuf_attr(RIMEBUF_ATTR_RELIABLE); params.fcf.panIdCompression = false; /* Insert IEEE 802.15.4 (2003) version bit. */ params.fcf.frameVersion = IEEE802154_2003; /* Increment and set the data sequence number. */ params.seq = macDSN++; /* Complete the addressing fields. */ /** \todo For phase 1 the addresses are all long. We'll need a mechanism in the rime attributes to tell the mac to use long or short for phase 2. */ params.fcf.srcAddrMode = LONGADDRMODE; params.dest_pid = ieee15_4ManagerAddress.get_dst_panid(); /* * If the output address is NULL in the Rime buf, then it is broadcast * on the 802.15.4 network. */ if(rimeaddr_cmp(rimebuf_addr(RIMEBUF_ADDR_RECEIVER), &rimeaddr_null) ) { /* Broadcast requires short address mode. */ params.fcf.destAddrMode = SHORTADDRMODE; params.dest_pid = BROADCASTPANDID; params.dest_addr.addr16 = BROADCASTADDR; } else { /* Phase 1.5 - end nodes send to anyone? */ memcpy(¶ms.dest_addr, (uint8_t *)rimebuf_addr(RIMEBUF_ADDR_RECEIVER), LONG_ADDR_LEN); /* Change from sicslowpan byte arrangement to sicslowmac */ byte_reverse((uint8_t*)¶ms.dest_addr.addr64, LONG_ADDR_LEN); /* Phase 1 - end nodes only sends to pan coordinator node. */ /* params.dest_addr.addr64 = ieee15_4ManagerAddress.get_coord_long_addr(); */ params.fcf.destAddrMode = LONGADDRMODE; } /* Set the source PAN ID to the global variable. */ params.src_pid = ieee15_4ManagerAddress.get_src_panid(); /* * Set up the source address using only the long address mode for * phase 1. */ params.src_addr.addr64 = ieee15_4ManagerAddress.get_long_addr(); /* Copy the payload data. */ params.payload_len = rimebuf_datalen(); params.payload = rimebuf_dataptr(); /* Create transmission frame. */ frame_tx_create(¶ms, &result); /* Log if needed */ LOG_FRAME(¶ms, &result); /* Retry up to this many times to send the packet if radio is busy */ uint8_t retry_count = 3; while(retry_count) { PRINTF("sicslowmac: sending packet of length %d to radio, result:", result.length); /* Send data to radio. */ radio_status_t rv = radio_send_data(result.length, result.frame); if (rv == RADIO_SUCCESS) { PRINTF(" Success\n"); return 1; /* True says that the packet could be sent */ } if (rv != RADIO_WRONG_STATE) { PRINTF(" Failed\n"); return 0; } PRINTF(" Radio busy, retrying\n"); /** \todo: Fix delay in sicslowmac so they do not block receiving */ //We have blocking delay here, it is safest this way. BUT doesn't solve the //problem of TX when you are RXing.. as the RX code can't execute! if (retry_count == 3) { _delay_ms(10); } else if (retry_count == 2) { _delay_ms(50); } else if (retry_count == 1) { _delay_ms(200); } retry_count--; } PRINTF("sicslowmac: Unable to send packet, dropped\n"); return 0;}/*---------------------------------------------------------------------------*//** * \brief Stub function that will be implemented in phase 2 to cause * end nodes to sleep. */intmac_wake(void){ return 1;}/*---------------------------------------------------------------------------*//** * \brief Stub function that will be implemented in phase 2 to cause * end nodes to sleep. */intmac_sleep(void){ return 1;}/*---------------------------------------------------------------------------*/const struct mac_driver *sicslowmac_init(const struct radio_driver *d){ /* AD: commented out the radio_driver code for now.*/ /* radio = d; radio->set_receive_function(input_packet); radio->on();*/ return &sicslowmac_driver;}/*---------------------------------------------------------------------------*//** * \brief This is the implementation of the 15.4 MAC Reset Request * primitive. * \param setDefaultPIB True if the default PIB values should be set. * \return Integer denoting success or failure. * \retval 0 Failure. * \retval 1 Success. * * Sets all PIB values to default. */voidsicslowmac_resetRequest (bool setDefaultPIB){ if(setDefaultPIB){ /* initialize all of the MAC PIB variables to their default values */ macCoordShortAddress = 0xffff; macDSN = rand() % 256; macSrcPANId = SOURCE_PAN_ID; macDstPANId = DEST_PAN_ID; macShortAddress = 0xffff; /* Setup the address of this device by reading a stored address from eeprom. */ /** \todo This might be read from the serial eeprom onboard Raven. */ AVR_ENTER_CRITICAL_REGION(); eeprom_read_block ((void *)&macLongAddr, EEPROMMACADDRESS, 8); byte_reverse((uint8_t *) &macLongAddr, 8); AVR_LEAVE_CRITICAL_REGION(); }}parsed_frame_t * sicslowmac_get_frame(void){ return parsed_frame;}/*---------------------------------------------------------------------------*/struct mac_driver * sicslowmac_get_driver(void){ return pmac_driver;}/*---------------------------------------------------------------------------*/PROCESS(mac_process, "802.15.4 MAC process");PROCESS_THREAD(mac_process, ev, data){ PROCESS_POLLHANDLER(mac_pollhandler()); PROCESS_BEGIN(); radio_status_t return_value; /* init radio */ /** \todo: this screws up if calosc is set to TRUE, find out why? */ return_value = radio_init(false, NULL, NULL, NULL);#if DEBUG if (return_value == RADIO_SUCCESS) { printf("Radio init successful.\n"); } else { printf("Radio init failed with return: %d\n", return_value); }#endif uint8_t eeprom_channel; uint8_t eeprom_check; eeprom_channel = eeprom_read_byte(9); eeprom_check = eeprom_read_byte(10); if ((eeprom_channel < 11) || (eeprom_channel > 26) || ((uint8_t)eeprom_channel != (uint8_t)~eeprom_check)) { eeprom_channel = 24; //Default } radio_set_operating_channel(eeprom_channel); radio_use_auto_tx_crc(true); radio_set_trx_state(TRX_OFF); mac_init(); /* Set up MAC function pointers and sicslowpan callback. */ pmac_driver->set_receive_function = setinput; pmac_driver->send = sicslowmac_dataRequest; sicslowpan_init(pmac_driver); ieee_15_4_init(&ieee15_4ManagerAddress); radio_set_trx_state(RX_AACK_ON); while(1) { PROCESS_YIELD(); mac_task(ev, data); } PROCESS_END();}void byte_reverse(uint8_t * bytes, uint8_t num){ uint8_t tempbyte; uint8_t i, j; i = 0; j = num - 1; while(i < j) { tempbyte = bytes[i]; bytes[i] = bytes[j]; bytes[j] = tempbyte; j--; i++; } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -