INT8U sendDiscoveredMotes(INT8U* pkBuf, INT8U payloadLen) { dn_error_t dnErr; INT8U rc; INT8U retries; loc_sendtoNW_t* pkToSend; INT8U returnVal; // fill in packet header pkToSend = (loc_sendtoNW_t*)pkBuf; pkToSend->locSendTo.socketId = loc_getSocketId(); pkToSend->locSendTo.destAddr = DN_MGR_IPV6_MULTICAST_ADDR; pkToSend->locSendTo.destPort = MOM_UDP_PORT; pkToSend->locSendTo.serviceType = DN_API_SERVICE_TYPE_BW; pkToSend->locSendTo.priority = DN_API_PRIORITY_MED; pkToSend->locSendTo.packetId = 0xFFFF; returnVal = RC_NO_RESOURCES; retries = 0; while (retries<MAX_RETRIES) { dnErr = dnm_loc_sendtoCmd( pkToSend, payloadLen, &rc ); if (dnErr==DN_ERR_NONE) { dnm_ucli_printf("INFO: motes sent\r\n"); break; } else { // increment number of retries retries++; // wait before trying again OSTimeDly(RETRY_PERIOD); } } return returnVal; }
/** \brief A demo task to show the use of the SPI. */ static void spiTask(void* unused) { INT8U i; dn_error_t dnErr; INT8U osErr; dn_spi_open_args_t spiOpenArgs; INT8U sendStatus; INT8U pkBuf[sizeof(loc_sendtoNW_t) + APP_DATA_BUF_SIZE]; loc_sendtoNW_t* pkToSend; dn_ioctl_spi_transfer_t spiTransfer; //===== initialize the configuration file initConfigFile(); //===== initialize packet variables pkToSend = (loc_sendtoNW_t*)pkBuf; //===== initialize SPI // open the SPI device spiOpenArgs.maxTransactionLenForCPHA_1 = 0; dnErr = dn_open( DN_SPI_DEV_ID, &spiOpenArgs, sizeof(spiOpenArgs) ); if ((dnErr < DN_ERR_NONE) && (dnErr != DN_ERR_STATE)) { dnm_cli_printf("unable to open SPI device, error %d\n\r",dnErr); } // initialize spi communication parameters spiTransfer.txData = spiNetApp_vars.spiTxBuffer; spiTransfer.rxData = spiNetApp_vars.spiRxBuffer; spiTransfer.transactionLen = sizeof(spiNetApp_vars.spiTxBuffer); spiTransfer.numSamples = 1; spiTransfer.startDelay = 0; spiTransfer.clockPolarity = DN_SPI_CPOL_0; spiTransfer.clockPhase = DN_SPI_CPHA_0; spiTransfer.bitOrder = DN_SPI_MSB_FIRST; spiTransfer.slaveSelect = DN_SPI_SSn0; spiTransfer.clockDivider = DN_SPI_CLKDIV_16; //===== wait for the mote to have joined OSSemPend(spiNetApp_vars.joinedSem,0,&osErr); ASSERT(osErr == OS_ERR_NONE); while(1) { // this is a task, it executes forever //===== step 1. write over SPI // set bytes to send for (i=0;i<sizeof(spiNetApp_vars.spiTxBuffer);i++) { spiNetApp_vars.spiTxBuffer[i] = i; } // send bytes dnErr = dn_ioctl( DN_SPI_DEV_ID, DN_IOCTL_SPI_TRANSFER, &spiTransfer, sizeof(spiTransfer) ); if (dnErr < DN_ERR_NONE) { dnm_cli_printf("Unable to communicate over SPI, err=%d\r\n",dnErr); } //===== step 2. print over CLI dnm_cli_printf("SPI sent: "); for (i=0;i<sizeof(spiNetApp_vars.spiTxBuffer);i++) { dnm_cli_printf(" %02x",spiNetApp_vars.spiTxBuffer[i]); } dnm_cli_printf("\r\n"); dnm_cli_printf("SPI received:"); for (i=0;i<sizeof(spiNetApp_vars.spiRxBuffer);i++) { dnm_cli_printf(" %02x",spiNetApp_vars.spiRxBuffer[i]); } dnm_cli_printf("\r\n"); //===== step 3. send data to manager // fill in packet "header" // Note: sendto->header is filled in dnm_loc_sendtoCmd pkToSend->locSendTo.socketId = loc_getSocketId(); pkToSend->locSendTo.destAddr = DN_MGR_IPV6_MULTICAST_ADDR; // IPv6 address pkToSend->locSendTo.destPort = WKP_SPI_NET; pkToSend->locSendTo.serviceType = DN_API_SERVICE_TYPE_BW; pkToSend->locSendTo.priority = DN_API_PRIORITY_MED; pkToSend->locSendTo.packetId = 0xFFFF; // fill in the packet payload memcpy(&pkToSend->locSendTo.payload[0],&spiNetApp_vars.spiRxBuffer[0],APP_DATA_BUF_SIZE); // send the packet dnErr = dnm_loc_sendtoCmd(pkToSend, APP_DATA_BUF_SIZE, &sendStatus); ASSERT (dnErr == DN_ERR_NONE); //===== step 4. pause until next iteration // this call blocks the task until the specified timeout expires (in ms) OSTimeDly(spiNetApp_vars.period); } }
void serial_api_rx_notification(INT8U* payload, INT8U payloadLen) { dn_error_t dnErr; serial_notif_ht* serial_notif; serial_notif_data_ht* serial_notif_data; INT8U dataLen; loc_sendtoNW_t* pkToSend; INT8U rc; // drop packet if wrong length if (payloadLen<=sizeof(serial_notif_ht)) { // print dnm_ucli_printf("ERROR: notification wrong length (%d bytes)\r\n",payloadLen); // disconnect OSSemPost(bridge_app_v.disconnectedSem); return; } // cast message serial_notif = (serial_notif_ht*)payload; // handle notification switch(serial_notif->notifType) { case PKT_NOTIF_TYPE_DATA: // cast serial message serial_notif_data = (serial_notif_data_ht*)serial_notif->payload; dataLen = payloadLen-sizeof(serial_notif_ht)-sizeof(serial_notif_data); if (dataLen+8>MAX_PAYLOAD_LENGTH) { dnm_ucli_printf("WARNING: data packet too long (%d bytes)\r\n",dataLen); } else { // prepare wireless packet pkToSend = (loc_sendtoNW_t*)bridge_app_v.pkBuf; pkToSend->locSendTo.socketId = loc_getSocketId(); pkToSend->locSendTo.destAddr = DN_MGR_IPV6_MULTICAST_ADDR; pkToSend->locSendTo.destPort = htons(serial_notif_data->dstPort); pkToSend->locSendTo.serviceType = DN_API_SERVICE_TYPE_BW; pkToSend->locSendTo.priority = DN_API_PRIORITY_MED; pkToSend->locSendTo.packetId = 0xFFFF; memcpy(&pkToSend->locSendTo.payload[0],serial_notif_data->macAddress,8); memcpy(&pkToSend->locSendTo.payload[8],serial_notif_data->data,dataLen); // send wireless packet dnErr = dnm_loc_sendtoCmd( pkToSend, 8+dataLen, &rc ); if (dnErr==DN_ERR_NONE) { dnm_ucli_printf("INFO: DATA tunneled\r\n"); } else { dnm_ucli_printf("ERROR: DATA tunneling dnErr=%d\r\n",dnErr); } } break; case PKT_NOTIF_TYPE_EVENT: case PKT_NOTIF_TYPE_HR: if (payloadLen+1>MAX_PAYLOAD_LENGTH) { dnm_ucli_printf("WARNING: notification too long (%d bytes)\r\n",dataLen); } else { // prepare wireless packet pkToSend = (loc_sendtoNW_t*)bridge_app_v.pkBuf; pkToSend->locSendTo.socketId = loc_getSocketId(); pkToSend->locSendTo.destAddr = DN_MGR_IPV6_MULTICAST_ADDR; pkToSend->locSendTo.destPort = MOM_UDP_PORT; pkToSend->locSendTo.serviceType = DN_API_SERVICE_TYPE_BW; pkToSend->locSendTo.priority = DN_API_PRIORITY_MED; pkToSend->locSendTo.packetId = 0xFFFF; pkToSend->locSendTo.payload[0] = MOM_RESP_DISPATCH_SERIALNOTIF; memcpy(&pkToSend->locSendTo.payload[1],payload,payloadLen); // send wireless packet dnErr = dnm_loc_sendtoCmd( pkToSend, 1+payloadLen, &rc ); if (dnErr==DN_ERR_NONE) { dnm_ucli_printf("INFO: NOTIF tunneled\r\n"); } else { dnm_ucli_printf("ERROR: NOTIF tunneling dnErr=%d\r\n",dnErr); } } break; case PKT_NOTIF_TYPE_IPDATA: case PKT_NOTIF_TYPE_LOG: dnm_ucli_printf("WARNING notifType %d not handled\r\n",serial_notif->notifType); break; default: // print dnm_ucli_printf("ERROR: unexpected notifType %d\r\n",serial_notif->notifType); // disconnect OSSemPost(bridge_app_v.disconnectedSem); return; } }
/** * \brief Request to transmit a frame. * * \param regId [in] RCM register Id * \param payload [in] Pointer to the first byte of the payload * \param payloadSize [in] Number of bytes in the payload * \param rateControlState [in] TODO * * \todo Document rateControlState * * \return RCM_NO_BUF_FREE Failure * \return RCM_ERR_OK Success */ rcm_error_t dnm_rcm_transmitFrame(INT8U regId, INT8U* payload, INT8U payloadSize, INT8U rateControlState) { dn_error_t locErr; INT8U status = 0; if(regId >= MAX_PENALTY_COUNT_BUF){ return RCM_INVALID_BUF_ID; } if (rateControlState == RATE_CTRL_ON) { /* skip the frame? */ if(rcm_v[regId].skipCount > 0) { rcm_v[regId].skipCount--; return RCM_RC_TX_FAILED; } } /* the destination address and destination port of the notifications is to be * retrieved in the from main module */ locErr = dnm_loc_sendtoCmd((loc_sendtoNW_t*)payload, payloadSize, &status); /* Transmission failed */ if((locErr != DN_ERR_NONE) || (status != DN_API_RC_OK)) { if (rateControlState == RATE_CTRL_ON) { /* Increment penalty count and restore skipcount to penalty count */ /* Clamp penalty count to MAX_PENALTY_COUNT */ if(rcm_v[regId].penaltyCount >= MAX_PENALTY_COUNT){ rcm_v[regId].penaltyCount = MAX_PENALTY_COUNT; } else { rcm_v[regId].penaltyCount++; } rcm_v[regId].skipCount = rcm_v[regId].penaltyCount; /* Did transmission fail due to negative ack ? */ if(status != DN_API_RC_OK) { dnm_ucli_trace(traceEnabled, "rc Tx req eng = %d, rejected, nack, pen = %d\r\n", regId, rcm_v[regId].penaltyCount); } else { dnm_ucli_trace(traceEnabled, "rc Tx req eng = %d, rejected, ack, pen = %d\r\n", regId, rcm_v[regId].penaltyCount); } } else { dnm_ucli_trace(traceEnabled, "rc=OFF, eng = %d, tx=failed\r\n", regId); } /* return errors;*/ return RCM_RC_TX_FAILED; } /* Transmission succeeded */ else { if (rateControlState == RATE_CTRL_ON) { /* Decrement penalty count and restore skipcount to penalty count */ if(rcm_v[regId].penaltyCount > 0) { rcm_v[regId].penaltyCount--; rcm_v[regId].skipCount = rcm_v[regId].penaltyCount; } dnm_ucli_trace(traceEnabled, "rc Tx req eng = %d, accepted, ack, pen = %d\r\n", regId, rcm_v[regId].penaltyCount); } else { dnm_ucli_trace(traceEnabled, "rc=OFF, eng = %d, tx=success\r\n", regId); } return RCM_ERR_OK; } }